]> git.saurik.com Git - wxWidgets.git/blob - src/msw/fontdlg.cpp
Fixed core dump for when there is no image list on the TreeCtrl
[wxWidgets.git] / src / msw / fontdlg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: fontdlg.cpp
3 // Purpose: wxFontDialog class
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 01/02/97
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "fontdlg.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include <stdio.h>
25 #include "wx/defs.h"
26 #include "wx/utils.h"
27 #include "wx/dialog.h"
28 #endif
29
30 #include "wx/fontdlg.h"
31
32 #include <windows.h>
33
34 #if !defined(__WIN32__) || defined(__SALFORDC__) || defined(__WXWINE__)
35 #include <commdlg.h>
36 #endif
37
38 #include "wx/msw/private.h"
39 #include "wx/cmndata.h"
40
41 #include <math.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #define wxDIALOG_DEFAULT_X 300
46 #define wxDIALOG_DEFAULT_Y 300
47
48 #if !USE_SHARED_LIBRARY
49 IMPLEMENT_DYNAMIC_CLASS(wxFontDialog, wxDialog)
50 #endif
51
52 /*
53 * wxFontDialog
54 */
55
56
57 wxFontDialog::wxFontDialog(void)
58 {
59 m_dialogParent = NULL;
60 }
61
62 wxFontDialog::wxFontDialog(wxWindow *parent, wxFontData *data)
63 {
64 Create(parent, data);
65 }
66
67 bool wxFontDialog::Create(wxWindow *parent, wxFontData *data)
68 {
69 m_dialogParent = parent;
70
71 if (data)
72 m_fontData = *data;
73 return TRUE;
74 }
75
76 int wxFontDialog::ShowModal(void)
77 {
78 CHOOSEFONT chooseFontStruct;
79 LOGFONT logFont;
80
81 DWORD flags = CF_TTONLY | CF_SCREENFONTS | CF_NOSIMULATIONS;
82
83 memset(&chooseFontStruct, 0, sizeof(CHOOSEFONT));
84
85 chooseFontStruct.lStructSize = sizeof(CHOOSEFONT);
86 chooseFontStruct.hwndOwner = (HWND) (m_dialogParent ? (HWND) m_dialogParent->GetHWND() : NULL);
87 chooseFontStruct.lpLogFont = &logFont;
88
89 if (m_fontData.initialFont.Ok())
90 {
91 flags |= CF_INITTOLOGFONTSTRUCT;
92 wxFillLogFont(&logFont, & m_fontData.initialFont);
93 }
94
95 chooseFontStruct.iPointSize = 0;
96 chooseFontStruct.rgbColors = RGB((BYTE)m_fontData.fontColour.Red(), (BYTE)m_fontData.fontColour.Green(), (BYTE)m_fontData.fontColour.Blue());
97
98 if (!m_fontData.GetAllowSymbols())
99 flags |= CF_ANSIONLY;
100 if (m_fontData.GetEnableEffects())
101 flags |= CF_EFFECTS;
102 if (m_fontData.GetShowHelp())
103 flags |= CF_SHOWHELP;
104 if (!(m_fontData.minSize == 0 && m_fontData.maxSize == 0))
105 {
106 chooseFontStruct.nSizeMin = m_fontData.minSize;
107 chooseFontStruct.nSizeMax = m_fontData.maxSize;
108 flags |= CF_LIMITSIZE;
109 }
110
111 chooseFontStruct.Flags = flags;
112 chooseFontStruct.nFontType = SCREEN_FONTTYPE;
113 bool success = (ChooseFont(&(chooseFontStruct)) != 0);
114
115 // Restore values
116 if (success)
117 {
118 m_fontData.fontColour.Set(GetRValue(chooseFontStruct.rgbColors), GetGValue(chooseFontStruct.rgbColors),
119 GetBValue(chooseFontStruct.rgbColors));
120 m_fontData.chosenFont = wxCreateFontFromLogFont(&logFont);
121 }
122
123 return success ? wxID_OK : wxID_CANCEL;
124 }
125
126 void wxFillLogFont(LOGFONT *logFont, wxFont *font)
127 {
128 BYTE ff_italic;
129 int ff_weight = 0;
130 int ff_family = 0;
131 wxString ff_face("");
132
133 switch (font->GetFamily())
134 {
135 case wxSCRIPT: ff_family = FF_SCRIPT ;
136 ff_face = "Script" ;
137 break ;
138 case wxDECORATIVE: ff_family = FF_DECORATIVE;
139 break;
140 case wxROMAN: ff_family = FF_ROMAN;
141 ff_face = "Times New Roman" ;
142 break;
143 case wxTELETYPE:
144 case wxMODERN: ff_family = FF_MODERN;
145 ff_face = "Courier New" ;
146 break;
147 case wxSWISS: ff_family = FF_SWISS;
148 ff_face = "Arial";
149 break;
150 case wxDEFAULT:
151 default: ff_family = FF_SWISS;
152 ff_face = "MS Sans Serif" ;
153 }
154
155 if (font->GetStyle() == wxITALIC || font->GetStyle() == wxSLANT)
156 ff_italic = 1;
157 else
158 ff_italic = 0;
159
160 if (font->GetWeight() == wxNORMAL)
161 ff_weight = FW_NORMAL;
162 else if (font->GetWeight() == wxLIGHT)
163 ff_weight = FW_LIGHT;
164 else if (font->GetWeight() == wxBOLD)
165 ff_weight = FW_BOLD;
166
167 // Have to get screen DC Caps, because a metafile will return 0.
168 HDC dc2 = ::GetDC(NULL);
169 int ppInch = ::GetDeviceCaps(dc2, LOGPIXELSY);
170 ::ReleaseDC(NULL, dc2);
171
172 // New behaviour: apparently ppInch varies according to
173 // Large/Small Fonts setting in Windows. This messes
174 // up fonts. So, set ppInch to a constant 96 dpi.
175 ppInch = 96;
176
177 #if wxFONT_SIZE_COMPATIBILITY
178 // Incorrect, but compatible with old wxWindows behaviour
179 int nHeight = (font->GetPointSize()*ppInch/72);
180 #else
181 // Correct for Windows compatibility
182 int nHeight = - (font->GetPointSize()*ppInch/72);
183 #endif
184
185 bool ff_underline = font->GetUnderlined();
186
187 ff_face = font->GetFaceName();
188
189 logFont->lfHeight = nHeight;
190 logFont->lfWidth = 0;
191 logFont->lfEscapement = 0;
192 logFont->lfOrientation = 0;
193 logFont->lfWeight = ff_weight;
194 logFont->lfItalic = ff_italic;
195 logFont->lfUnderline = (BYTE)ff_underline;
196 logFont->lfStrikeOut = 0;
197 logFont->lfCharSet = ANSI_CHARSET;
198 logFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
199 logFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
200 logFont->lfQuality = PROOF_QUALITY;
201 logFont->lfPitchAndFamily = DEFAULT_PITCH | ff_family;
202 wxStrcpy(logFont->lfFaceName, ff_face);
203 }
204
205 wxFont wxCreateFontFromLogFont(LOGFONT *logFont) // , bool createNew)
206 {
207 int fontFamily = wxSWISS;
208 int fontStyle = wxNORMAL;
209 int fontWeight = wxNORMAL;
210 int fontPoints = 10;
211 bool fontUnderline = FALSE;
212 wxChar *fontFace = NULL;
213
214 // int lfFamily = logFont->lfPitchAndFamily & 0xF0;
215 int lfFamily = logFont->lfPitchAndFamily;
216 if (lfFamily & FIXED_PITCH)
217 lfFamily -= FIXED_PITCH;
218 if (lfFamily & VARIABLE_PITCH)
219 lfFamily -= VARIABLE_PITCH;
220
221 switch (lfFamily)
222 {
223 case FF_ROMAN:
224 fontFamily = wxROMAN;
225 break;
226 case FF_SWISS:
227 fontFamily = wxSWISS;
228 break;
229 case FF_SCRIPT:
230 fontFamily = wxSCRIPT;
231 break;
232 case FF_MODERN:
233 fontFamily = wxMODERN;
234 break;
235 case FF_DECORATIVE:
236 fontFamily = wxDECORATIVE;
237 break;
238 default:
239 fontFamily = wxSWISS;
240 break;
241 }
242 switch (logFont->lfWeight)
243 {
244 case FW_LIGHT:
245 fontWeight = wxLIGHT;
246 break;
247 case FW_NORMAL:
248 fontWeight = wxNORMAL;
249 break;
250 case FW_BOLD:
251 fontWeight = wxBOLD;
252 break;
253 default:
254 fontWeight = wxNORMAL;
255 break;
256 }
257 if (logFont->lfItalic)
258 fontStyle = wxITALIC;
259 else
260 fontStyle = wxNORMAL;
261
262 if (logFont->lfUnderline)
263 fontUnderline = TRUE;
264
265 if (logFont->lfFaceName)
266 fontFace = logFont->lfFaceName;
267
268 HDC dc2 = ::GetDC(NULL);
269
270 if ( logFont->lfHeight < 0 )
271 logFont->lfHeight = - logFont->lfHeight;
272 fontPoints = abs(72*logFont->lfHeight/GetDeviceCaps(dc2, LOGPIXELSY));
273 ::ReleaseDC(NULL, dc2);
274
275 // if ( createNew )
276 return wxFont(fontPoints, fontFamily, fontStyle, fontWeight, fontUnderline, fontFace);
277 // else
278 // return wxTheFontList->FindOrCreateFont(fontPoints, fontFamily, fontStyle, fontWeight, fontUnderline, fontFace);
279 }
280
281