1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/msw/stattext.cpp
3 // Purpose:     wxStaticText
4 // Author:      Julian Smart
5 // Modified by:
6 // Created:     04/01/98
7 // Copyright:   (c) Julian Smart
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13 
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17 
18 #if wxUSE_STATTEXT
19 
20 #include "wx/stattext.h"
21 
22 #ifndef WX_PRECOMP
23     #include "wx/event.h"
24     #include "wx/app.h"
25     #include "wx/brush.h"
26     #include "wx/dcclient.h"
27     #include "wx/settings.h"
28 #endif
29 
30 #include "wx/msw/private.h"
31 
Create(wxWindow * parent,wxWindowID id,const wxString & label,const wxPoint & pos,const wxSize & size,long style,const wxString & name)32 bool wxStaticText::Create(wxWindow *parent,
33                           wxWindowID id,
34                           const wxString& label,
35                           const wxPoint& pos,
36                           const wxSize& size,
37                           long style,
38                           const wxString& name)
39 {
40     if ( !CreateControl(parent, id, pos, size, style, wxDefaultValidator, name) )
41         return false;
42 
43     if ( !MSWCreateControl(wxT("STATIC"), wxEmptyString, pos, size) )
44         return false;
45 
46     // we set the label here and not through MSWCreateControl() because we
47     // need to do many operation on it for ellipsization&markup support
48     SetLabel(label);
49 
50     // as we didn't pass the correct label to MSWCreateControl(), it didn't set
51     // the initial size correctly -- do it now
52     InvalidateBestSize();
53     SetInitialSize(size);
54 
55     // NOTE: if the label contains ampersand characters which are interpreted as
56     //       accelerators, they will be rendered (at least on WinXP) only if the
57     //       static text is placed inside a window class which correctly handles
58     //       focusing by TAB traversal (e.g. wxPanel).
59 
60     return true;
61 }
62 
MSWGetStyle(long style,WXDWORD * exstyle) const63 WXDWORD wxStaticText::MSWGetStyle(long style, WXDWORD *exstyle) const
64 {
65     WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle);
66 
67     // translate the alignment flags to the Windows ones
68     //
69     // note that both wxALIGN_LEFT and SS_LEFT are equal to 0 so we shouldn't
70     // test for them using & operator
71     if ( style & wxALIGN_CENTRE_HORIZONTAL )
72         msStyle |= SS_CENTER;
73     else if ( style & wxALIGN_RIGHT )
74         msStyle |= SS_RIGHT;
75     else
76         msStyle |= SS_LEFT;
77 
78 #ifdef SS_ENDELLIPSIS
79     // this style is necessary to receive mouse events
80     // Win NT and later have the SS_ENDELLIPSIS style which is useful to us:
81     if (wxGetOsVersion() == wxOS_WINDOWS_NT)
82     {
83         // for now, add the SS_ENDELLIPSIS style if wxST_ELLIPSIZE_END is given;
84         // we may need to remove it later in ::SetLabel() if the given label
85         // has newlines
86         if ( style & wxST_ELLIPSIZE_END )
87             msStyle |= SS_ENDELLIPSIS;
88     }
89 #endif // SS_ENDELLIPSIS
90 
91     msStyle |= SS_NOTIFY;
92 
93     return msStyle;
94 }
95 
DoGetBestClientSize() const96 wxSize wxStaticText::DoGetBestClientSize() const
97 {
98     wxClientDC dc(const_cast<wxStaticText *>(this));
99     wxFont font(GetFont());
100     if (!font.IsOk())
101         font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
102 
103     dc.SetFont(font);
104 
105     wxCoord widthTextMax, heightTextTotal;
106     dc.GetMultiLineTextExtent(GetLabelText(), &widthTextMax, &heightTextTotal);
107 
108 #ifdef __WXWINCE__
109     if ( widthTextMax )
110         widthTextMax += 2;
111 #endif // __WXWINCE__
112 
113     // This extra pixel is a hack we use to ensure that a wxStaticText
114     // vertically centered around the same position as a wxTextCtrl shows its
115     // text on exactly the same baseline. It is not clear why is this needed
116     // nor even whether this works in all cases, but it does work, at least
117     // with the default fonts, under Windows XP, 7 and 8, so just use it for
118     // now.
119     //
120     // In the future we really ought to provide a way for each of the controls
121     // to provide information about the position of the baseline for the text
122     // it shows and use this information in the sizer code when centering the
123     // controls vertically, otherwise we simply can't ensure that the text is
124     // always on the same line, e.g. even with this hack wxComboBox text is
125     // still not aligned to the same position.
126     heightTextTotal += 1;
127 
128     return wxSize(widthTextMax, heightTextTotal);
129 }
130 
DoSetSize(int x,int y,int w,int h,int sizeFlags)131 void wxStaticText::DoSetSize(int x, int y, int w, int h, int sizeFlags)
132 {
133     // note: we first need to set the size and _then_ call UpdateLabel
134     wxStaticTextBase::DoSetSize(x, y, w, h, sizeFlags);
135 
136 #ifdef SS_ENDELLIPSIS
137     // do we need to ellipsize the contents?
138     long styleReal = ::GetWindowLong(GetHwnd(), GWL_STYLE);
139     if ( !(styleReal & SS_ENDELLIPSIS) )
140     {
141         // we don't have SS_ENDELLIPSIS style:
142         // we need to (eventually) do ellipsization ourselves
143         UpdateLabel();
144     }
145     //else: we don't or the OS will do it for us
146 #endif // SS_ENDELLIPSIS
147 
148     // we need to refresh the window after changing its size as the standard
149     // control doesn't always update itself properly
150     Refresh();
151 }
152 
SetLabel(const wxString & label)153 void wxStaticText::SetLabel(const wxString& label)
154 {
155 #ifdef SS_ENDELLIPSIS
156     long styleReal = ::GetWindowLong(GetHwnd(), GWL_STYLE);
157     if ( HasFlag(wxST_ELLIPSIZE_END) &&
158           wxGetOsVersion() == wxOS_WINDOWS_NT )
159     {
160         // adding SS_ENDELLIPSIS or SS_ENDELLIPSIS "disables" the correct
161         // newline handling in static texts: the newlines in the labels are
162         // shown as square. Thus we don't use it even on newer OS when
163         // the static label contains a newline.
164         if ( label.Contains(wxT('\n')) )
165             styleReal &= ~SS_ENDELLIPSIS;
166         else
167             styleReal |= SS_ENDELLIPSIS;
168 
169         ::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal);
170     }
171     else // style not supported natively
172     {
173         styleReal &= ~SS_ENDELLIPSIS;
174         ::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal);
175     }
176 #endif // SS_ENDELLIPSIS
177 
178     // save the label in m_labelOrig with both the markup (if any) and
179     // the mnemonics characters (if any)
180     m_labelOrig = label;
181 
182 #ifdef SS_ENDELLIPSIS
183     if ( styleReal & SS_ENDELLIPSIS )
184         DoSetLabel(GetLabel());
185     else
186 #endif // SS_ENDELLIPSIS
187         DoSetLabel(GetEllipsizedLabel());
188 
189     // adjust the size of the window to fit to the label unless autoresizing is
190     // disabled
191     if ( !HasFlag(wxST_NO_AUTORESIZE) &&
192          !IsEllipsized() )  // if ellipsize is ON, then we don't want to get resized!
193     {
194         InvalidateBestSize();
195         DoSetSize(wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord,
196                   wxSIZE_AUTO_WIDTH | wxSIZE_AUTO_HEIGHT);
197     }
198 }
199 
SetFont(const wxFont & font)200 bool wxStaticText::SetFont(const wxFont& font)
201 {
202     bool ret = wxControl::SetFont(font);
203 
204     // adjust the size of the window to fit to the label unless autoresizing is
205     // disabled
206     if ( !HasFlag(wxST_NO_AUTORESIZE) )
207     {
208         InvalidateBestSize();
209         DoSetSize(wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord,
210                   wxSIZE_AUTO_WIDTH | wxSIZE_AUTO_HEIGHT);
211     }
212 
213     return ret;
214 }
215 
216 // for wxST_ELLIPSIZE_* support:
217 
DoGetLabel() const218 wxString wxStaticText::DoGetLabel() const
219 {
220     return wxGetWindowText(GetHwnd());
221 }
222 
DoSetLabel(const wxString & str)223 void wxStaticText::DoSetLabel(const wxString& str)
224 {
225     SetWindowText(GetHwnd(), str.c_str());
226 }
227 
228 
229 #endif // wxUSE_STATTEXT
230