dialog.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 612 行 · 第 1/2 页
CPP
612 行
// show dialog modally
int wxDialog::ShowModal()
{
wxASSERT_MSG( !IsModal(), _T("wxDialog::ShowModal() reentered?") );
m_endModalCalled = false;
Show();
// EndModal may have been called from InitDialog handler (called from
// inside Show()), which would cause an infinite loop if we didn't take it
// into account
if ( !m_endModalCalled )
{
// modal dialog needs a parent window, so try to find one
wxWindow *parent = GetParent();
if ( !parent )
{
parent = FindSuitableParent();
}
// remember where the focus was
wxWindow *oldFocus = m_oldFocus;
if ( !oldFocus )
{
// VZ: do we really want to do this?
oldFocus = parent;
}
// We have to remember the HWND because we need to check
// the HWND still exists (oldFocus can be garbage when the dialog
// exits, if it has been destroyed)
HWND hwndOldFocus = oldFocus ? GetHwndOf(oldFocus) : NULL;
// enter and run the modal loop
{
wxDialogModalDataTiedPtr modalData(&m_modalData,
new wxDialogModalData(this));
modalData->RunLoop();
}
// and restore focus
// Note that this code MUST NOT access the dialog object's data
// in case the object has been deleted (which will be the case
// for a modal dialog that has been destroyed before calling EndModal).
if ( oldFocus && (oldFocus != this) && ::IsWindow(hwndOldFocus))
{
// This is likely to prove that the object still exists
if (wxFindWinFromHandle((WXHWND) hwndOldFocus) == oldFocus)
oldFocus->SetFocus();
}
}
return GetReturnCode();
}
void wxDialog::EndModal(int retCode)
{
wxASSERT_MSG( IsModal(), _T("EndModal() called for non modal dialog") );
m_endModalCalled = true;
SetReturnCode(retCode);
Hide();
}
void wxDialog::EndDialog(int rc)
{
if ( IsModal() )
EndModal(rc);
else
Hide();
}
// ----------------------------------------------------------------------------
// wxWin event handlers
// ----------------------------------------------------------------------------
bool wxDialog::EmulateButtonClickIfPresent(int id)
{
wxButton *btn = wxDynamicCast(FindWindow(id), wxButton);
if ( !btn || !btn->IsEnabled() || !btn->IsShown() )
return false;
btn->MSWCommand(BN_CLICKED, 0 /* unused */);
return true;
}
// Standard buttons
void wxDialog::OnOK(wxCommandEvent& WXUNUSED(event))
{
if ( Validate() && TransferDataFromWindow() )
{
EndDialog(wxID_OK);
}
}
void wxDialog::OnApply(wxCommandEvent& WXUNUSED(event))
{
if ( Validate() )
TransferDataFromWindow();
// TODO probably need to disable the Apply button until things change again
}
void wxDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
{
EndDialog(wxID_CANCEL);
}
void wxDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
{
// We'll send a Cancel message by default, which may close the dialog.
// Check for looping if the Cancel event handler calls Close().
// Note that if a cancel button and handler aren't present in the dialog,
// nothing will happen when you close the dialog via the window manager, or
// via Close(). We wouldn't want to destroy the dialog by default, since
// the dialog may have been created on the stack. However, this does mean
// that calling dialog->Close() won't delete the dialog unless the handler
// for wxID_CANCEL does so. So use Destroy() if you want to be sure to
// destroy the dialog. The default OnCancel (above) simply ends a modal
// dialog, and hides a modeless dialog.
// VZ: this is horrible and MT-unsafe. Can't we reuse some of these global
// lists here? don't dare to change it now, but should be done later!
static wxList closing;
if ( closing.Member(this) )
return;
closing.Append(this);
wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
cancelEvent.SetEventObject( this );
GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog
closing.DeleteObject(this);
}
void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event))
{
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
Refresh();
}
#ifdef __POCKETPC__
// Responds to the OK button in a PocketPC titlebar. This
// can be overridden, or you can change the id used for
// sending the event, by calling SetAffirmativeId.
bool wxDialog::DoOK()
{
const int idOk = GetAffirmativeId();
if ( EmulateButtonClickIfPresent(idOk) )
return true;
wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetAffirmativeId());
event.SetEventObject(this);
return GetEventHandler()->ProcessEvent(event);
}
#endif // __POCKETPC__
#if wxUSE_TOOLBAR && defined(__POCKETPC__)
// create main toolbar by calling OnCreateToolBar()
wxToolBar* wxDialog::CreateToolBar(long style, wxWindowID winid, const wxString& name)
{
m_dialogToolBar = OnCreateToolBar(style, winid, name);
return m_dialogToolBar;
}
// return a new toolbar
wxToolBar *wxDialog::OnCreateToolBar(long style,
wxWindowID winid,
const wxString& name)
{
return new wxToolMenuBar(this, winid,
wxDefaultPosition, wxDefaultSize,
style, name);
}
#endif
// ---------------------------------------------------------------------------
// dialog Windows messages processing
// ---------------------------------------------------------------------------
bool wxDialog::MSWProcessMessage(WXMSG* pMsg)
{
const MSG * const msg = wx_reinterpret_cast(MSG *, pMsg);
if ( msg->message == WM_KEYDOWN && msg->wParam == VK_ESCAPE )
{
int idCancel = GetEscapeId();
switch ( idCancel )
{
case wxID_NONE:
// don't handle Esc specially at all
break;
case wxID_ANY:
// this value is special: it means translate Esc to wxID_CANCEL
// but if there is no such button, then fall back to wxID_OK
if ( EmulateButtonClickIfPresent(wxID_CANCEL) )
return true;
idCancel = wxID_OK;
// fall through
default:
// translate Esc to button press for the button with given id
if ( EmulateButtonClickIfPresent(idCancel) )
return true;
}
}
return wxDialogBase::MSWProcessMessage(pMsg);
}
WXLRESULT wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
{
WXLRESULT rc = 0;
bool processed = false;
switch ( message )
{
#ifdef __WXWINCE__
// react to pressing the OK button in the title
case WM_COMMAND:
{
switch ( LOWORD(wParam) )
{
#ifdef __POCKETPC__
case IDOK:
processed = DoOK();
if (!processed)
processed = !Close();
#endif
#ifdef __SMARTPHONE__
case IDM_LEFT:
case IDM_RIGHT:
processed = HandleCommand( LOWORD(wParam) , 0 , NULL );
break;
#endif // __SMARTPHONE__
}
break;
}
#endif
case WM_CLOSE:
// if we can't close, tell the system that we processed the
// message - otherwise it would close us
processed = !Close();
break;
case WM_SIZE:
// the Windows dialogs unfortunately are not meant to be resizeable
// at all and their standard class doesn't include CS_[VH]REDRAW
// styles which means that the window is not refreshed properly
// after the resize and no amount of WS_CLIPCHILDREN/SIBLINGS can
// help with it - so we have to refresh it manually which certainly
// creates flicker but at least doesn't show garbage on the screen
rc = wxWindow::MSWWindowProc(message, wParam, lParam);
processed = true;
if ( HasFlag(wxFULL_REPAINT_ON_RESIZE) )
{
::InvalidateRect(GetHwnd(), NULL, false /* erase bg */);
}
break;
#ifndef __WXMICROWIN__
case WM_SETCURSOR:
// we want to override the busy cursor for modal dialogs:
// typically, wxBeginBusyCursor() is called and then a modal dialog
// is shown, but the modal dialog shouldn't have hourglass cursor
if ( IsModal() && wxIsBusy() )
{
// set our cursor for all windows (but see below)
wxCursor cursor = m_cursor;
if ( !cursor.Ok() )
cursor = wxCURSOR_ARROW;
::SetCursor(GetHcursorOf(cursor));
// in any case, stop here and don't let wxWindow process this
// message (it would set the busy cursor)
processed = true;
// but return false to tell the child window (if the event
// comes from one of them and not from ourselves) that it can
// set its own cursor if it has one: thus, standard controls
// (e.g. text ctrl) still have correct cursors in a dialog
// invoked while wxIsBusy()
rc = false;
}
break;
#endif // __WXMICROWIN__
}
if ( !processed )
rc = wxWindow::MSWWindowProc(message, wParam, lParam);
return rc;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?