]> git.saurik.com Git - wxWidgets.git/blame - src/msw/commandlinkbutton.cpp
guard against nullptr
[wxWidgets.git] / src / msw / commandlinkbutton.cpp
CommitLineData
3571e1ad
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/msw/commandlinkbutton.cpp
3// Purpose: wxCommandLinkButton
4// Author: Rickard Westerlund
5// Created: 2010-06-14
6// RCS-ID: $Id$
7// Copyright: (c) 2010 wxWidgets team
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// ----------------------------------------------------------------------------
12// headers
13// ----------------------------------------------------------------------------
14
15// For compilers that support precompilation, includes "wx.h".
16#include "wx/wxprec.h"
17
18#ifdef __BORLANDC__
19 #pragma hdrstop
20#endif
21
22#if wxUSE_COMMANDLINKBUTTON
23
24#ifndef WX_PRECOMP
25 #include "wx/app.h"
26 #include "wx/dcclient.h"
27#endif
28
29#include "wx/commandlinkbutton.h"
30#include "wx/msw/private.h"
31#include "wx/msw/private/button.h"
32#include "wx/msw/private/dc.h"
33#include "wx/private/window.h"
34
35#ifndef BCM_SETNOTE
36 #define BCM_SETNOTE 0x1609
37#endif
38
39#ifndef BS_COMMANDLINK
40 #define BS_COMMANDLINK 0xE
41#endif
42
43// ----------------------------------------------------------------------------
44// Helper functions
45// ----------------------------------------------------------------------------
46
47namespace
48{
49
50inline bool HasNativeCommandLinkButton()
51{
52 return wxGetWinVersion() >= wxWinVersion_6;
53}
54
55} // anonymous namespace
56
57// ----------------------------------------------------------------------------
58// Command link button
59// ----------------------------------------------------------------------------
60
61bool wxCommandLinkButton::Create(wxWindow *parent,
62 wxWindowID id,
63 const wxString& mainLabel,
64 const wxString& note,
65 const wxPoint& pos,
66 const wxSize& size,
67 long style,
68 const wxValidator& validator,
69 const wxString& name)
70{
71 if ( ! wxGenericCommandLinkButton::Create(parent,
72 id,
73 mainLabel,
74 note,
75 pos,
76 size,
77 style,
78 validator,
79 name) )
80 return false;
81
82 SetMainLabelAndNote(mainLabel, note);
83 SetInitialSize();
84
85 return true;
86}
87
88void
89wxCommandLinkButton::SetMainLabelAndNote(const wxString& mainLabel,
90 const wxString& note)
91{
92 if ( HasNativeCommandLinkButton() )
93 {
94 wxButton::SetLabel(mainLabel);
95 ::SendMessage(m_hWnd, BCM_SETNOTE, 0, (LPARAM) note.wx_str());
96
97 // Preserve the user-specified label for GetLabel()
98 m_labelOrig = mainLabel;
99 if ( !note.empty() )
100 m_labelOrig << '\n' << note;
101 }
102 else
103 {
104 wxGenericCommandLinkButton::SetMainLabelAndNote(mainLabel, note);
105 }
106}
107
108WXDWORD wxCommandLinkButton::MSWGetStyle(long style, WXDWORD *exstyle) const
109{
110 WXDWORD ret = wxButton::MSWGetStyle(style, exstyle);
111 if ( HasNativeCommandLinkButton() )
112 ret |= BS_COMMANDLINK;
113
114 return ret;
115}
116
117bool wxCommandLinkButton::HasNativeBitmap() const
118{
119 return HasNativeCommandLinkButton();
120}
121
122// ----------------------------------------------------------------------------
123// size management including autosizing
124// ----------------------------------------------------------------------------
125
126// Margin measures can be found at
127// http://expression.microsoft.com/en-us/ee662150.aspx
128namespace
129{
130 const int MAINLABEL_TOP_MARGIN = 16; // Includes image top margin.
131 const int MAINLABEL_NOTE_LEFT_MARGIN = 23;
132 const int NOTE_TOP_MARGIN = 21;
133 const int NOTE_BOTTOM_MARGIN = 1;
134 const int MAINLABEL_NOTE_MARGIN = NOTE_TOP_MARGIN - MAINLABEL_TOP_MARGIN;
135};
136
137wxSize wxCommandLinkButton::DoGetBestSize() const
138{
139 wxSize size;
140
141 // account for the text part if we have it or if we don't have any image at
142 // all (buttons initially created with empty label should still have a non
143 // zero size)
144 if ( ShowsLabel() || !m_imageData )
145 {
146 int flags = 0;
147 if ( GetAuthNeeded() )
148 flags |= wxMSWButton::Size_AuthNeeded;
149
150 wxCommandLinkButton *thisButton =
151 const_cast<wxCommandLinkButton *>(this);
152 wxClientDC dc(thisButton);
153
154 wxFont noteFont = dc.GetFont();
155
156 // 4/3 is the relationship between main label and note font sizes.
157 dc.SetFont(noteFont.Scaled(4.0f/3.0f));
158 size = dc.GetMultiLineTextExtent(GetLabelText(GetMainLabel()));
159
160 dc.SetFont(noteFont);
161 wxSize noteSize = dc.GetMultiLineTextExtent(GetLabelText(GetNote()));
162
163 if ( noteSize.x > size.x )
164 size.x = noteSize.x;
165 size.y += noteSize.y;
166
167 size = wxMSWButton::GetFittingSize(thisButton,
168 size,
169 flags);
170
171 // The height of a standard command link button is 25 and 35 DLUs for
172 // single lines and two lines respectively. Width is not accounted for.
173 int heightDef = GetNote().AfterFirst('\n').empty() ? 25 : 35;
174 wxSize sizeDef = thisButton->ConvertDialogToPixels(wxSize(50,
175 heightDef));
176
177 if ( size.y < sizeDef.y )
178 size.y = sizeDef.y;
179 }
180
181 if ( m_imageData )
182 {
183 AdjustForBitmapSize(size);
184 }
185 else
186 {
187 // The default image size is 16x16.
188 size.x += 16;
189 if ( size.y < 16 )
190 size.y = 16;
191 }
192
193 size.x += MAINLABEL_NOTE_LEFT_MARGIN;
194 size.y += MAINLABEL_TOP_MARGIN + NOTE_BOTTOM_MARGIN;
195 if ( !GetNote().empty() )
196 size.y += MAINLABEL_NOTE_MARGIN;
197
198 CacheBestSize(size);
199
200 return size;
201}
202
203#endif // wxUSE_COMMANDLINKBUTTON