implement support for custom button labels in wxMessageBox under MSW; refactor the code to reuse the existing setters in Mac ports for MSW as well
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55475 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -25,26 +25,22 @@ DECLARE_WXCOCOA_OBJC_CLASS(NSAlert);
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/generic/msgdlgg.h"
|
|
||||||
|
|
||||||
#if wxUSE_COCOA_NATIVE_MSGDLG
|
#if wxUSE_COCOA_NATIVE_MSGDLG
|
||||||
#define wxMessageDialog wxCocoaMessageDialog
|
#define wxMessageDialog wxCocoaMessageDialog
|
||||||
#else
|
#else
|
||||||
|
#include "wx/generic/msgdlgg.h"
|
||||||
|
|
||||||
#define wxMessageDialog wxGenericMessageDialog
|
#define wxMessageDialog wxGenericMessageDialog
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxMsgDialog
|
// wxCocoaMessageDialog
|
||||||
//-------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
class WXDLLIMPEXP_CORE wxCocoaMessageDialog
|
||||||
class WXDLLIMPEXP_CORE wxCocoaMessageDialog: public wxMessageDialogBase
|
: public wxMessageDialogWithCustomLabels
|
||||||
{
|
{
|
||||||
DECLARE_DYNAMIC_CLASS(wxCocoaMessageDialog)
|
|
||||||
DECLARE_NO_COPY_CLASS(wxCocoaMessageDialog)
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
wxCocoaMessageDialog(wxWindow *parent,
|
wxCocoaMessageDialog(wxWindow *parent,
|
||||||
const wxString& message,
|
const wxString& message,
|
||||||
@@ -52,28 +48,23 @@ public:
|
|||||||
long style = wxOK|wxCENTRE,
|
long style = wxOK|wxCENTRE,
|
||||||
const wxPoint& pos = wxDefaultPosition);
|
const wxPoint& pos = wxDefaultPosition);
|
||||||
|
|
||||||
virtual ~wxCocoaMessageDialog();
|
|
||||||
|
|
||||||
virtual int ShowModal();
|
virtual int ShowModal();
|
||||||
|
|
||||||
// customization of the message box
|
|
||||||
virtual bool SetYesNoLabels(const wxString& yes,const wxString& no);
|
|
||||||
virtual bool SetYesNoCancelLabels(const wxString& yes, const wxString& no, const wxString& cancel);
|
|
||||||
virtual bool SetOKLabel(const wxString& ok);
|
|
||||||
virtual bool SetOKCancelLabels(const wxString& ok, const wxString& cancel);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// not supported for message dialog
|
// not supported for message dialog
|
||||||
virtual void DoSetSize(int WXUNUSED(x), int WXUNUSED(y),
|
virtual void DoSetSize(int WXUNUSED(x), int WXUNUSED(y),
|
||||||
int WXUNUSED(width), int WXUNUSED(height),
|
int WXUNUSED(width), int WXUNUSED(height),
|
||||||
int WXUNUSED(sizeFlags) = wxSIZE_AUTO) {}
|
int WXUNUSED(sizeFlags) = wxSIZE_AUTO) {}
|
||||||
|
|
||||||
private:
|
// override wxMessageDialogWithCustomLabels method to get rid of
|
||||||
wxString m_yes,
|
// accelerators in the custom label strings
|
||||||
m_no,
|
//
|
||||||
m_ok,
|
// VZ: I have no idea _why_ do we do this but the old version did and
|
||||||
m_cancel;
|
// I didn't want to change the existing behaviour
|
||||||
|
virtual void DoSetCustomLabel(wxString& var, const wxString& value);
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_CLASS(wxCocoaMessageDialog)
|
||||||
|
DECLARE_NO_COPY_CLASS(wxCocoaMessageDialog)
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _WX_MSGDLG_H_
|
#endif // _WX_MSGDLG_H_
|
||||||
|
@@ -107,8 +107,101 @@ protected:
|
|||||||
m_extendedMessage,
|
m_extendedMessage,
|
||||||
m_caption;
|
m_caption;
|
||||||
long m_dialogStyle;
|
long m_dialogStyle;
|
||||||
|
|
||||||
|
DECLARE_NO_COPY_CLASS(wxMessageDialogBase)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// this is a helper class for native wxMessageDialog implementations which need
|
||||||
|
// to store the custom button labels as member variables and then use them in
|
||||||
|
// ShowModal() (there could conceivably be a port which would have some native
|
||||||
|
// functions for setting these labels immediately and we also don't need to
|
||||||
|
// store them at all if custom labels are not supported, which is why we do
|
||||||
|
// this in a separate class and not wxMessageDialogBase itself)
|
||||||
|
#if defined(__WXCOCOA__) || defined(__WXMAC__) || defined(__WXMSW__)
|
||||||
|
|
||||||
|
class WXDLLIMPEXP_CORE wxMessageDialogWithCustomLabels
|
||||||
|
: public wxMessageDialogBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// ctors
|
||||||
|
wxMessageDialogWithCustomLabels() { }
|
||||||
|
wxMessageDialogWithCustomLabels(wxWindow *parent,
|
||||||
|
const wxString& message,
|
||||||
|
const wxString& caption,
|
||||||
|
long style)
|
||||||
|
: wxMessageDialogBase(parent, message, caption, style)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// customization of the message box buttons
|
||||||
|
virtual bool SetYesNoLabels(const wxString& yes,const wxString& no)
|
||||||
|
{
|
||||||
|
DoSetCustomLabel(m_yes, yes);
|
||||||
|
DoSetCustomLabel(m_no, no);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool SetYesNoCancelLabels(const wxString& yes,
|
||||||
|
const wxString& no,
|
||||||
|
const wxString& cancel)
|
||||||
|
{
|
||||||
|
DoSetCustomLabel(m_yes, yes);
|
||||||
|
DoSetCustomLabel(m_no, no);
|
||||||
|
DoSetCustomLabel(m_cancel, cancel);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool SetOKLabel(const wxString& ok)
|
||||||
|
{
|
||||||
|
DoSetCustomLabel(m_ok, ok);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool SetOKCancelLabels(const wxString& ok, const wxString& cancel)
|
||||||
|
{
|
||||||
|
DoSetCustomLabel(m_ok, ok);
|
||||||
|
DoSetCustomLabel(m_cancel, cancel);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// test if any custom labels were set
|
||||||
|
bool HasCustomLabels() const
|
||||||
|
{
|
||||||
|
return !(m_ok.empty() && m_cancel.empty() &&
|
||||||
|
m_yes.empty() && m_no.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
// these functions return the label to be used for the button which is
|
||||||
|
// either a custom label explicitly set by the user or the default label,
|
||||||
|
// i.e. they always return a valid string
|
||||||
|
wxString GetYesLabel() const { return m_yes.empty() ? _("Yes") : m_yes; }
|
||||||
|
wxString GetNoLabel() const { return m_no.empty() ? _("No") : m_no; }
|
||||||
|
wxString GetOKLabel() const { return m_ok.empty() ? _("OK") : m_ok; }
|
||||||
|
wxString GetCancelLabel() const
|
||||||
|
{ return m_cancel.empty() ? _("Cancel") : m_cancel; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// this function is called by our public SetXXXLabels() and should assign
|
||||||
|
// the value to var with possibly some transformation (e.g. Cocoa version
|
||||||
|
// currently uses this to remove any accelerators from the button strings)
|
||||||
|
virtual void DoSetCustomLabel(wxString& var, const wxString& value)
|
||||||
|
{
|
||||||
|
var = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// labels for the buttons, initially empty meaning that the defaults should
|
||||||
|
// be used, use GetYes/No/OK/CancelLabel() to access them
|
||||||
|
wxString m_yes,
|
||||||
|
m_no,
|
||||||
|
m_ok,
|
||||||
|
m_cancel;
|
||||||
|
|
||||||
|
DECLARE_NO_COPY_CLASS(wxMessageDialogWithCustomLabels)
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ports needing wxMessageDialogWithCustomLabels
|
||||||
|
|
||||||
#if defined(__WX_COMPILING_MSGDLGG_CPP__) || \
|
#if defined(__WX_COMPILING_MSGDLGG_CPP__) || \
|
||||||
defined(__WXUNIVERSAL__) || defined(__WXGPE__) || \
|
defined(__WXUNIVERSAL__) || defined(__WXGPE__) || \
|
||||||
(defined(__WXGTK__) && !defined(__WXGTK20__))
|
(defined(__WXGTK__) && !defined(__WXGTK20__))
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
#ifndef _WX_MSGBOXDLG_H_
|
#ifndef _WX_MSGBOXDLG_H_
|
||||||
#define _WX_MSGBOXDLG_H_
|
#define _WX_MSGBOXDLG_H_
|
||||||
|
|
||||||
class WXDLLIMPEXP_CORE wxMessageDialog : public wxMessageDialogBase
|
class WXDLLIMPEXP_CORE wxMessageDialog : public wxMessageDialogWithCustomLabels
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxMessageDialog(wxWindow *parent,
|
wxMessageDialog(wxWindow *parent,
|
||||||
@@ -20,17 +20,24 @@ public:
|
|||||||
const wxString& caption = wxMessageBoxCaptionStr,
|
const wxString& caption = wxMessageBoxCaptionStr,
|
||||||
long style = wxOK|wxCENTRE,
|
long style = wxOK|wxCENTRE,
|
||||||
const wxPoint& WXUNUSED(pos) = wxDefaultPosition)
|
const wxPoint& WXUNUSED(pos) = wxDefaultPosition)
|
||||||
: wxMessageDialogBase(parent, message, caption, style)
|
: wxMessageDialogWithCustomLabels(parent, message, caption, style)
|
||||||
{
|
{
|
||||||
m_hook = NULL;
|
m_hook = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual int ShowModal();
|
virtual int ShowModal();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// hook procedure used to adjust the message box beyond what the standard
|
||||||
|
// MessageBox() function can do for us
|
||||||
static WXLRESULT wxCALLBACK HookFunction(int code, WXWPARAM, WXLPARAM);
|
static WXLRESULT wxCALLBACK HookFunction(int code, WXWPARAM, WXLPARAM);
|
||||||
|
|
||||||
|
// adjust the button labels
|
||||||
|
//
|
||||||
|
// this is called from HookFunction() and our HWND is valid at this moment
|
||||||
|
void AdjustButtonLabels();
|
||||||
|
|
||||||
|
|
||||||
WXHANDLE m_hook; // HHOOK used to position the message box
|
WXHANDLE m_hook; // HHOOK used to position the message box
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxMessageDialog)
|
DECLARE_DYNAMIC_CLASS(wxMessageDialog)
|
||||||
|
@@ -24,24 +24,12 @@ public:
|
|||||||
|
|
||||||
virtual int ShowModal();
|
virtual int ShowModal();
|
||||||
|
|
||||||
// customization of the message box
|
|
||||||
virtual bool SetYesNoLabels(const wxString& yes,const wxString& no);
|
|
||||||
virtual bool SetYesNoCancelLabels(const wxString& yes, const wxString& no, const wxString& cancel);
|
|
||||||
virtual bool SetOKLabel(const wxString& ok);
|
|
||||||
virtual bool SetOKCancelLabels(const wxString& ok, const wxString& cancel);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// not supported for message dialog
|
// not supported for message dialog
|
||||||
virtual void DoSetSize(int WXUNUSED(x), int WXUNUSED(y),
|
virtual void DoSetSize(int WXUNUSED(x), int WXUNUSED(y),
|
||||||
int WXUNUSED(width), int WXUNUSED(height),
|
int WXUNUSED(width), int WXUNUSED(height),
|
||||||
int WXUNUSED(sizeFlags) = wxSIZE_AUTO) {}
|
int WXUNUSED(sizeFlags) = wxSIZE_AUTO) {}
|
||||||
|
|
||||||
// labels for the buttons
|
|
||||||
wxString m_yes,
|
|
||||||
m_no,
|
|
||||||
m_ok,
|
|
||||||
m_cancel;
|
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxMessageDialog)
|
DECLARE_DYNAMIC_CLASS(wxMessageDialog)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -47,13 +47,10 @@ wxCocoaMessageDialog::wxCocoaMessageDialog(wxWindow *parent,
|
|||||||
const wxString& message,
|
const wxString& message,
|
||||||
const wxString& caption,
|
const wxString& caption,
|
||||||
long style,
|
long style,
|
||||||
const wxPoint& pos) : wxMessageDialogBase(parent,message,caption,style)
|
const wxPoint& pos)
|
||||||
|
: wxMessageDialogWithCustomLabels(parent, message, caption, style)
|
||||||
{
|
{
|
||||||
|
|
||||||
//m_caption = caption;
|
|
||||||
//m_message = message;
|
|
||||||
|
|
||||||
//wxTopLevelWindows.Append((wxWindowBase*)this);
|
|
||||||
wxTopLevelWindows.Append(this);
|
wxTopLevelWindows.Append(this);
|
||||||
|
|
||||||
wxASSERT(CreateBase(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,style,wxDefaultValidator,wxDialogNameStr));
|
wxASSERT(CreateBase(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,style,wxDefaultValidator,wxDialogNameStr));
|
||||||
@@ -64,16 +61,13 @@ wxCocoaMessageDialog::wxCocoaMessageDialog(wxWindow *parent,
|
|||||||
|
|
||||||
m_cocoaNSWindow = nil;
|
m_cocoaNSWindow = nil;
|
||||||
m_cocoaNSView = nil;
|
m_cocoaNSView = nil;
|
||||||
|
|
||||||
m_yes = _("Yes");
|
|
||||||
m_no = _("No");
|
|
||||||
m_ok = _("OK");
|
|
||||||
m_cancel = _("Cancel");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCocoaMessageDialog::~wxCocoaMessageDialog()
|
void wxCocoaMessageDialog::DoSetCustomLabel(wxString& var, const wxString& value)
|
||||||
{
|
{
|
||||||
|
wxMessageDialogWithCustomLabels::DoSetCustomLabel(var, value);
|
||||||
|
|
||||||
|
var.Replace("&", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxCocoaMessageDialog::ShowModal()
|
int wxCocoaMessageDialog::ShowModal()
|
||||||
@@ -121,21 +115,21 @@ int wxCocoaMessageDialog::ShowModal()
|
|||||||
{
|
{
|
||||||
if ( style & wxNO_DEFAULT )
|
if ( style & wxNO_DEFAULT )
|
||||||
{
|
{
|
||||||
[alert addButtonWithTitle:wxNSStringWithWxString(m_no)];
|
[alert addButtonWithTitle:wxNSStringWithWxString(GetNoLabel())];
|
||||||
[alert addButtonWithTitle:wxNSStringWithWxString(m_yes)];
|
[alert addButtonWithTitle:wxNSStringWithWxString(GetYesLabel())];
|
||||||
buttonId[0] = wxID_NO;
|
buttonId[0] = wxID_NO;
|
||||||
buttonId[1] = wxID_YES;
|
buttonId[1] = wxID_YES;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[alert addButtonWithTitle:wxNSStringWithWxString(m_yes)];
|
[alert addButtonWithTitle:wxNSStringWithWxString(GetYesLabel())];
|
||||||
[alert addButtonWithTitle:wxNSStringWithWxString(m_no)];
|
[alert addButtonWithTitle:wxNSStringWithWxString(GetNoLabel())];
|
||||||
buttonId[0] = wxID_YES;
|
buttonId[0] = wxID_YES;
|
||||||
buttonId[1] = wxID_NO;
|
buttonId[1] = wxID_NO;
|
||||||
}
|
}
|
||||||
if (style & wxCANCEL)
|
if (style & wxCANCEL)
|
||||||
{
|
{
|
||||||
[alert addButtonWithTitle:wxNSStringWithWxString(m_cancel)];
|
[alert addButtonWithTitle:wxNSStringWithWxString(GetCancelLabel())];
|
||||||
buttonId[2] = wxID_CANCEL;
|
buttonId[2] = wxID_CANCEL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,10 +138,10 @@ int wxCocoaMessageDialog::ShowModal()
|
|||||||
// the MSW implementation even shows an OK button if it is not specified, we'll do the same
|
// the MSW implementation even shows an OK button if it is not specified, we'll do the same
|
||||||
buttonId[0] = wxID_OK;
|
buttonId[0] = wxID_OK;
|
||||||
// using null as default title does not work on earlier systems
|
// using null as default title does not work on earlier systems
|
||||||
[alert addButtonWithTitle:wxNSStringWithWxString(m_ok)];
|
[alert addButtonWithTitle:wxNSStringWithWxString(GetOKLabel())];
|
||||||
if (style & wxCANCEL)
|
if (style & wxCANCEL)
|
||||||
{
|
{
|
||||||
[alert addButtonWithTitle:wxNSStringWithWxString(m_cancel)];
|
[alert addButtonWithTitle:wxNSStringWithWxString(GetCancelLabel())];
|
||||||
buttonId[1] = wxID_CANCEL;
|
buttonId[1] = wxID_CANCEL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,38 +152,5 @@ int wxCocoaMessageDialog::ShowModal()
|
|||||||
return buttonId[ret-NSAlertFirstButtonReturn];
|
return buttonId[ret-NSAlertFirstButtonReturn];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxCocoaMessageDialog::SetYesNoLabels(const wxString& yes,const wxString& no)
|
|
||||||
{
|
|
||||||
m_yes = yes;
|
|
||||||
m_yes.Replace(_("&"),_(""));
|
|
||||||
m_no = no;
|
|
||||||
m_no.Replace(_("&"),_(""));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool wxCocoaMessageDialog::SetYesNoCancelLabels(const wxString& yes, const wxString& no, const wxString& cancel)
|
|
||||||
{
|
|
||||||
m_yes = yes;
|
|
||||||
m_yes.Replace(_("&"),_(""));
|
|
||||||
m_no = no;
|
|
||||||
m_no.Replace(_("&"),_(""));
|
|
||||||
m_cancel = cancel;
|
|
||||||
m_cancel.Replace(_("&"),_(""));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool wxCocoaMessageDialog::SetOKLabel(const wxString& ok)
|
|
||||||
{
|
|
||||||
m_ok = ok;
|
|
||||||
m_ok.Replace(_("&"),_(""));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool wxCocoaMessageDialog::SetOKCancelLabels(const wxString& ok, const wxString& cancel)
|
|
||||||
{
|
|
||||||
m_ok = ok;
|
|
||||||
m_ok.Replace(_("&"),_(""));
|
|
||||||
m_cancel = cancel;
|
|
||||||
m_cancel.Replace(_("&"),_(""));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // wxUSE_DIRDLG
|
#endif // wxUSE_DIRDLG
|
||||||
|
|
||||||
|
@@ -38,6 +38,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h"
|
||||||
|
#include "wx/msw/private/button.h"
|
||||||
|
#include "wx/msw/private/metrics.h"
|
||||||
|
|
||||||
|
#if wxUSE_MSGBOX_HOOK
|
||||||
|
#include "wx/fontutil.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// For MB_TASKMODAL
|
// For MB_TASKMODAL
|
||||||
#ifdef __WXWINCE__
|
#ifdef __WXWINCE__
|
||||||
@@ -83,30 +89,146 @@ wxMessageDialog::HookFunction(int code, WXWPARAM wParam, WXLPARAM lParam)
|
|||||||
const HHOOK hhook = (HHOOK)wnd->m_hook;
|
const HHOOK hhook = (HHOOK)wnd->m_hook;
|
||||||
const LRESULT rc = ::CallNextHookEx(hhook, code, wParam, lParam);
|
const LRESULT rc = ::CallNextHookEx(hhook, code, wParam, lParam);
|
||||||
|
|
||||||
if ( code == HC_ACTION && lParam )
|
if ( code == HCBT_ACTIVATE )
|
||||||
{
|
|
||||||
const CWPRETSTRUCT * const s = (CWPRETSTRUCT *)lParam;
|
|
||||||
|
|
||||||
if ( s->message == HCBT_ACTIVATE )
|
|
||||||
{
|
{
|
||||||
// we won't need this hook any longer
|
// we won't need this hook any longer
|
||||||
::UnhookWindowsHookEx(hhook);
|
::UnhookWindowsHookEx(hhook);
|
||||||
wnd->m_hook = NULL;
|
wnd->m_hook = NULL;
|
||||||
HookMap().erase(tid);
|
HookMap().erase(tid);
|
||||||
|
|
||||||
|
wnd->SetHWND((HWND)wParam);
|
||||||
|
|
||||||
|
// centre the message box on its parent if requested
|
||||||
if ( wnd->GetMessageDialogStyle() & wxCENTER )
|
if ( wnd->GetMessageDialogStyle() & wxCENTER )
|
||||||
{
|
|
||||||
wnd->SetHWND(s->hwnd);
|
|
||||||
wnd->Center(); // center on parent
|
wnd->Center(); // center on parent
|
||||||
wnd->SetHWND(NULL);
|
|
||||||
}
|
|
||||||
//else: default behaviour, center on screen
|
//else: default behaviour, center on screen
|
||||||
}
|
|
||||||
|
// also update the labels if necessary
|
||||||
|
if ( wnd->HasCustomLabels() )
|
||||||
|
wnd->AdjustButtonLabels();
|
||||||
|
|
||||||
|
// there seems to be no reason to leave it set
|
||||||
|
wnd->SetHWND(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
// helper of AdjustButtonLabels(): set window position expressed in screen
|
||||||
|
// coordinates, whether the window is child or top level
|
||||||
|
void MoveWindowToScreenRect(HWND hwnd, RECT rc)
|
||||||
|
{
|
||||||
|
if ( const HWND hwndParent = ::GetAncestor(hwnd, GA_PARENT) )
|
||||||
|
{
|
||||||
|
// map to parent window coordinates (notice that a RECT is laid out as
|
||||||
|
// 2 consecutive POINTs)
|
||||||
|
::MapWindowPoints(HWND_DESKTOP, hwndParent,
|
||||||
|
reinterpret_cast<POINT *>(&rc), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
::MoveWindow(hwnd,
|
||||||
|
rc.left, rc.top,
|
||||||
|
rc.right - rc.left, rc.bottom - rc.top,
|
||||||
|
FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper of AdjustButtonLabels(): move the given window by dx
|
||||||
|
//
|
||||||
|
// works for both child and top level windows
|
||||||
|
void OffsetWindow(HWND hwnd, int dx)
|
||||||
|
{
|
||||||
|
RECT rc = wxGetWindowRect(hwnd);
|
||||||
|
|
||||||
|
rc.left += dx;
|
||||||
|
rc.right += dx;
|
||||||
|
|
||||||
|
MoveWindowToScreenRect(hwnd, rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
void wxMessageDialog::AdjustButtonLabels()
|
||||||
|
{
|
||||||
|
// changing the button labels is the easy part but we also need to ensure
|
||||||
|
// that the buttons are big enough for the label strings and increase their
|
||||||
|
// size (and hence the size of the message box itself) if they are not
|
||||||
|
|
||||||
|
// TODO-RTL: check whether this works correctly in RTL
|
||||||
|
|
||||||
|
// the order in this array is the one in which buttons appear in the
|
||||||
|
// message box
|
||||||
|
const static struct ButtonAccessors
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
wxString (wxMessageDialog::*getter)() const;
|
||||||
|
}
|
||||||
|
buttons[] =
|
||||||
|
{
|
||||||
|
{ IDYES, &wxMessageDialog::GetYesLabel },
|
||||||
|
{ IDNO, &wxMessageDialog::GetNoLabel },
|
||||||
|
{ IDOK, &wxMessageDialog::GetOKLabel },
|
||||||
|
{ IDCANCEL, &wxMessageDialog::GetCancelLabel },
|
||||||
|
};
|
||||||
|
|
||||||
|
// this contains the amount by which we increased the message box width
|
||||||
|
int dx = 0;
|
||||||
|
|
||||||
|
const NONCLIENTMETRICS& ncm = wxMSWImpl::GetNonClientMetrics();
|
||||||
|
const wxFont fontMsgBox(wxNativeFontInfo(ncm.lfMessageFont));
|
||||||
|
|
||||||
|
// we want to use this font in GetTextExtent() calls below but we don't
|
||||||
|
// want to send WM_SETFONT to the message box, who knows how is it going to
|
||||||
|
// react to it (right now it doesn't seem to do anything but what if this
|
||||||
|
// changes)
|
||||||
|
wxWindowBase::SetFont(fontMsgBox);
|
||||||
|
|
||||||
|
for ( unsigned n = 0; n < WXSIZEOF(buttons); n++ )
|
||||||
|
{
|
||||||
|
const HWND hwndBtn = ::GetDlgItem(GetHwnd(), buttons[n].id);
|
||||||
|
if ( !hwndBtn )
|
||||||
|
continue; // it's ok, not all buttons are always present
|
||||||
|
|
||||||
|
const wxString label = (this->*buttons[n].getter)();
|
||||||
|
const wxSize sizeLabel = wxWindowBase::GetTextExtent(label);
|
||||||
|
|
||||||
|
// check if the button is big enough for this label
|
||||||
|
RECT rc = wxGetWindowRect(hwndBtn);
|
||||||
|
const int widthOld = rc.right - rc.left;
|
||||||
|
const int widthNew = wxMSWButton::GetFittingSize(this, sizeLabel).x;
|
||||||
|
const int dw = widthNew - widthOld;
|
||||||
|
if ( dw > 0 )
|
||||||
|
{
|
||||||
|
// we need to resize the button
|
||||||
|
rc.right += dw;
|
||||||
|
MoveWindowToScreenRect(hwndBtn, rc);
|
||||||
|
|
||||||
|
// and also move all the other buttons
|
||||||
|
for ( unsigned m = n + 1; m < WXSIZEOF(buttons); m++ )
|
||||||
|
{
|
||||||
|
const HWND hwndBtnNext = ::GetDlgItem(GetHwnd(), buttons[m].id);
|
||||||
|
if ( hwndBtnNext )
|
||||||
|
OffsetWindow(hwndBtnNext, dw);
|
||||||
|
}
|
||||||
|
|
||||||
|
dx += dw;
|
||||||
|
}
|
||||||
|
|
||||||
|
::SetWindowText(hwndBtn, label.wx_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// resize the message box itself if needed
|
||||||
|
if ( dx )
|
||||||
|
OffsetWindow(GetHwnd(), dx);
|
||||||
|
|
||||||
|
// surprisingly, we don't need to resize the static text control, it seems
|
||||||
|
// to adjust itself to the new size, at least under Windows 2003
|
||||||
|
// (TODO: test if this happens on older Windows versions)
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_MSGBOX_HOOK
|
#endif // wxUSE_MSGBOX_HOOK
|
||||||
|
|
||||||
|
|
||||||
@@ -187,10 +309,11 @@ int wxMessageDialog::ShowModal()
|
|||||||
|
|
||||||
#if wxUSE_MSGBOX_HOOK
|
#if wxUSE_MSGBOX_HOOK
|
||||||
// install the hook if we need to position the dialog in a non-default way
|
// install the hook if we need to position the dialog in a non-default way
|
||||||
if ( wxStyle & wxCENTER )
|
// or change the labels
|
||||||
|
if ( (wxStyle & wxCENTER) || HasCustomLabels() )
|
||||||
{
|
{
|
||||||
const DWORD tid = ::GetCurrentThreadId();
|
const DWORD tid = ::GetCurrentThreadId();
|
||||||
m_hook = ::SetWindowsHookEx(WH_CALLWNDPROCRET,
|
m_hook = ::SetWindowsHookEx(WH_CBT,
|
||||||
&wxMessageDialog::HookFunction, NULL, tid);
|
&wxMessageDialog::HookFunction, NULL, tid);
|
||||||
HookMap()[tid] = this;
|
HookMap()[tid] = this;
|
||||||
}
|
}
|
||||||
|
@@ -30,40 +30,8 @@ wxMessageDialog::wxMessageDialog(wxWindow *parent,
|
|||||||
const wxString& caption,
|
const wxString& caption,
|
||||||
long style,
|
long style,
|
||||||
const wxPoint& WXUNUSED(pos))
|
const wxPoint& WXUNUSED(pos))
|
||||||
: wxMessageDialogBase(parent, message, caption, style)
|
: wxMessageDialogWithCustomLabels(parent, message, caption, style)
|
||||||
{
|
{
|
||||||
m_yes = _("Yes");
|
|
||||||
m_no = _("No");
|
|
||||||
m_ok = _("OK");
|
|
||||||
m_cancel = _("Cancel");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxMessageDialog::SetYesNoLabels(const wxString& yes,const wxString& no)
|
|
||||||
{
|
|
||||||
m_yes = yes;
|
|
||||||
m_no = no;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxMessageDialog::SetYesNoCancelLabels(const wxString& yes, const wxString& no, const wxString& cancel)
|
|
||||||
{
|
|
||||||
m_yes = yes;
|
|
||||||
m_no = no;
|
|
||||||
m_cancel = cancel;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxMessageDialog::SetOKLabel(const wxString& ok)
|
|
||||||
{
|
|
||||||
m_ok = ok;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxMessageDialog::SetOKCancelLabels(const wxString& ok, const wxString& cancel)
|
|
||||||
{
|
|
||||||
m_ok = ok;
|
|
||||||
m_cancel = cancel;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxMessageDialog::ShowModal()
|
int wxMessageDialog::ShowModal()
|
||||||
@@ -113,10 +81,10 @@ int wxMessageDialog::ShowModal()
|
|||||||
wxCFStringRef cfTitle( msgtitle, GetFont().GetEncoding() );
|
wxCFStringRef cfTitle( msgtitle, GetFont().GetEncoding() );
|
||||||
wxCFStringRef cfText( msgtext, GetFont().GetEncoding() );
|
wxCFStringRef cfText( msgtext, GetFont().GetEncoding() );
|
||||||
|
|
||||||
wxCFStringRef cfNoString( m_no.c_str(), GetFont().GetEncoding() );
|
wxCFStringRef cfNoString( GetNoLabel().c_str(), GetFont().GetEncoding() );
|
||||||
wxCFStringRef cfYesString( m_yes.c_str(), GetFont().GetEncoding() );
|
wxCFStringRef cfYesString( GetYesLabel().c_str(), GetFont().GetEncoding() );
|
||||||
wxCFStringRef cfOKString( m_ok.c_str() , GetFont().GetEncoding()) ;
|
wxCFStringRef cfOKString( GetOKLabel().c_str() , GetFont().GetEncoding()) ;
|
||||||
wxCFStringRef cfCancelString( m_cancel.c_str(), GetFont().GetEncoding() );
|
wxCFStringRef cfCancelString( GetCancelLabel().c_str(), GetFont().GetEncoding() );
|
||||||
|
|
||||||
int buttonId[4] = { 0, 0, 0, wxID_CANCEL /* time-out */ };
|
int buttonId[4] = { 0, 0, 0, wxID_CANCEL /* time-out */ };
|
||||||
|
|
||||||
@@ -167,10 +135,10 @@ int wxMessageDialog::ShowModal()
|
|||||||
short result;
|
short result;
|
||||||
|
|
||||||
AlertStdCFStringAlertParamRec param;
|
AlertStdCFStringAlertParamRec param;
|
||||||
wxCFStringRef cfNoString( m_no.c_str(), GetFont().GetEncoding() );
|
wxCFStringRef cfNoString( GetNoLabel().c_str(), GetFont().GetEncoding() );
|
||||||
wxCFStringRef cfYesString( m_yes.c_str(), GetFont().GetEncoding() );
|
wxCFStringRef cfYesString( GetYesLabel().c_str(), GetFont().GetEncoding() );
|
||||||
wxCFStringRef cfOKString( m_ok.c_str(), GetFont().GetEncoding() );
|
wxCFStringRef cfOKString( GetOKLabel().c_str(), GetFont().GetEncoding() );
|
||||||
wxCFStringRef cfCancelString( m_cancel.c_str(), GetFont().GetEncoding() );
|
wxCFStringRef cfCancelString( GetCancelLabel().c_str(), GetFont().GetEncoding() );
|
||||||
|
|
||||||
wxCFStringRef cfTitle( msgtitle, GetFont().GetEncoding() );
|
wxCFStringRef cfTitle( msgtitle, GetFont().GetEncoding() );
|
||||||
wxCFStringRef cfText( msgtext, GetFont().GetEncoding() );
|
wxCFStringRef cfText( msgtext, GetFont().GetEncoding() );
|
||||||
|
Reference in New Issue
Block a user