1 /* 2 * COMMDLG - Font Dialog 3 * 4 * Copyright 1994 Martin Ayotte 5 * Copyright 1996 Albrecht Kleine 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include "cdlg.h" 23 24 typedef struct 25 { 26 HWND hWnd1; 27 HWND hWnd2; 28 LPCHOOSEFONTW lpcf32w; 29 int added; 30 } CFn_ENUMSTRUCT, *LPCFn_ENUMSTRUCT; 31 32 33 static const WCHAR strWineFontData[] = {'_','_','W','I','N','E','_','F','O','N','T','D','L','G','D','A','T','A',0}; 34 static const WCHAR strWineFontData_a[] = 35 {'_','_','W','I','N','E','_','F','O','N','T','D','L','G','D','A','T','A','_','A',0}; 36 static const WCHAR chooseFontW[] = {'C','H','O','O','S','E','_','F','O','N','T',0}; 37 static const WCHAR fontsizefmtW[] = {'%','d',0}; 38 39 /* image list with TrueType bitmaps and more */ 40 static HIMAGELIST himlTT = 0; 41 #define TTBITMAP_XSIZE 20 /* x-size of the bitmaps */ 42 43 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); 44 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); 45 46 /* There is a table here of all charsets, and the sample text for each. 47 * There is a second table that translates a charset into an index into 48 * the first table. 49 */ 50 51 #define CI(cs) ((IDS_CHARSET_##cs)-IDS_CHARSET_ANSI) 52 53 54 static const WCHAR stWestern[]={'A','a','B','b','Y','y','Z','z',0}; /* Western and default */ 55 static const WCHAR stSymbol[]={'S','y','m','b','o','l',0}; /* Symbol */ 56 static const WCHAR stShiftJis[]={'A','a',0x3042,0x3041,0x30a2,0x30a1,0x4e9c,0x5b87,0}; /* Shift JIS */ 57 static const WCHAR stHangul[]={0xac00,0xb098,0xb2e4,'A','a','B','Y','y','Z','z',0}; /* Hangul */ 58 static const WCHAR stGB2312[]={0x5fae,0x8f6f,0x4e2d,0x6587,0x8f6f,0x4ef6,0}; /* GB2312 */ 59 static const WCHAR stBIG5[]={0x4e2d,0x6587,0x5b57,0x578b,0x7bc4,0x4f8b,0}; /* BIG5 */ 60 static const WCHAR stGreek[]={'A','a','B','b',0x0391,0x03b1,0x0392,0x03b2,0}; /* Greek */ 61 static const WCHAR stTurkish[]={'A','a','B','b',0x011e,0x011f,0x015e,0x015f,0}; /* Turkish */ 62 static const WCHAR stHebrew[]={'A','a','B','b',0x05e0,0x05e1,0x05e9,0x05ea,0}; /* Hebrew */ 63 static const WCHAR stArabic[]={'A','a','B','b',0x0627,0x0628,0x062c,0x062f,0x0647,0x0648,0x0632,0};/* Arabic */ 64 static const WCHAR stBaltic[]={'A','a','B','b','Y','y','Z','z',0}; /* Baltic */ 65 static const WCHAR stVietname[]={'A','a','B','b',0x01a0,0x01a1,0x01af,0x01b0,0}; /* Vietnamese */ 66 static const WCHAR stCyrillic[]={'A','a','B','b',0x0411,0x0431,0x0424,0x0444,0}; /* Cyrillic */ 67 static const WCHAR stEastEur[]={'A','a','B','b',0xc1,0xe1,0xd4,0xf4,0}; /* East European */ 68 static const WCHAR stThai[]={'A','a','B','b',0x0e2d,0x0e31,0x0e01,0x0e29,0x0e23,0x0e44,0x0e17,0x0e22,0}; /* Thai */ 69 static const WCHAR stJohab[]={0xac00,0xb098,0xb2e4,'A','a','B','Y','y','Z','z',0}; /* Johab */ 70 static const WCHAR stMac[]={'A','a','B','b','Y','y','Z','z',0}; /* Mac */ 71 static const WCHAR stOEM[]={'A','a','B','b',0xf8,0xf1,0xfd,0}; /* OEM */ 72 /* the following character sets actually behave different (Win2K observation): 73 * the sample string is 'sticky': it uses the sample string of the previous 74 * selected character set. That behaviour looks like some default, which is 75 * not (yet) implemented. */ 76 static const WCHAR stVISCII[]={'A','a','B','b',0}; /* VISCII */ 77 static const WCHAR stTCVN[]={'A','a','B','b',0}; /* TCVN */ 78 static const WCHAR stKOI8[]={'A','a','B','b',0}; /* KOI-8 */ 79 static const WCHAR stIso88593[]={'A','a','B','b',0}; /* ISO-8859-3 */ 80 static const WCHAR stIso88594[]={'A','a','B','b',0}; /* ISO-8859-4 */ 81 static const WCHAR stIso885910[]={'A','a','B','b',0}; /* ISO-8859-10 */ 82 static const WCHAR stCeltic[]={'A','a','B','b',0};/* Celtic */ 83 84 static const WCHAR * const sample_lang_text[]={ 85 stWestern,stSymbol,stShiftJis,stHangul,stGB2312, 86 stBIG5,stGreek,stTurkish,stHebrew,stArabic, 87 stBaltic,stVietname,stCyrillic,stEastEur,stThai, 88 stJohab,stMac,stOEM,stVISCII,stTCVN, 89 stKOI8,stIso88593,stIso88594,stIso885910,stCeltic}; 90 91 92 static const BYTE CHARSET_ORDER[256]={ 93 CI(ANSI), 0, CI(SYMBOL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(MAC), 0, 0, 98 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101 CI(JIS), CI(HANGUL), CI(JOHAB), 0, 0, 0, CI(GB2312), 0, CI(BIG5), 0, 0, 0, 0, 0, 0, 0, 102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103 0, CI(GREEK), CI(TURKISH), CI(VIETNAMESE), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104 0, CI(HEBREW), CI(ARABIC), 0, 0, 0, 0, 0, 0, 0, CI(BALTIC), 0, 0, 0, 0, 0, 105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(RUSSIAN), 0, 0, 0, 106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(THAI), 0, 107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(EE), 0, 108 CI(VISCII), CI(TCVN), CI(KOI8), CI(ISO3), CI(ISO4), CI(ISO10), CI(CELTIC), 0, 0, 0, 0, 0, 0, 0, 0, CI(OEM), 109 }; 110 111 static const struct { 112 DWORD mask; 113 const char *name; 114 } cfflags[] = { 115 #define XX(x) { x, #x }, 116 XX(CF_SCREENFONTS) 117 XX(CF_PRINTERFONTS) 118 XX(CF_SHOWHELP) 119 XX(CF_ENABLEHOOK) 120 XX(CF_ENABLETEMPLATE) 121 XX(CF_ENABLETEMPLATEHANDLE) 122 XX(CF_INITTOLOGFONTSTRUCT) 123 XX(CF_USESTYLE) 124 XX(CF_EFFECTS) 125 XX(CF_APPLY) 126 XX(CF_ANSIONLY) 127 XX(CF_NOVECTORFONTS) 128 XX(CF_NOSIMULATIONS) 129 XX(CF_LIMITSIZE) 130 XX(CF_FIXEDPITCHONLY) 131 XX(CF_WYSIWYG) 132 XX(CF_FORCEFONTEXIST) 133 XX(CF_SCALABLEONLY) 134 XX(CF_TTONLY) 135 XX(CF_NOFACESEL) 136 XX(CF_NOSTYLESEL) 137 XX(CF_NOSIZESEL) 138 XX(CF_SELECTSCRIPT) 139 XX(CF_NOSCRIPTSEL) 140 XX(CF_NOVERTFONTS) 141 #undef XX 142 }; 143 144 static void _dump_cf_flags(DWORD cflags) 145 { 146 unsigned int i; 147 148 for (i = 0; i < sizeof(cfflags)/sizeof(cfflags[0]); i++) 149 if (cfflags[i].mask & cflags) 150 TRACE("%s|",cfflags[i].name); 151 TRACE("\n"); 152 } 153 154 /*********************************************************************** 155 * ChooseFontW (COMDLG32.@) 156 * 157 * Create a font dialog box. 158 * 159 * PARAMS 160 * lpChFont [I/O] in: information to initialize the dialog box. 161 * out: User's color selection 162 * 163 * RETURNS 164 * TRUE: Ok button clicked. 165 * FALSE: Cancel button clicked, or error. 166 */ 167 BOOL WINAPI ChooseFontW(LPCHOOSEFONTW lpChFont) 168 { 169 LPCVOID template; 170 HRSRC hResInfo; 171 HINSTANCE hDlginst; 172 HGLOBAL hDlgTmpl; 173 174 TRACE("(%p)\n", lpChFont); 175 176 if ( (lpChFont->Flags&CF_ENABLETEMPLATEHANDLE)!=0 ) 177 { 178 template=lpChFont->hInstance; 179 } else 180 { 181 if ( (lpChFont->Flags&CF_ENABLETEMPLATE)!=0 ) 182 { 183 hDlginst=lpChFont->hInstance; 184 if( !(hResInfo = FindResourceW(hDlginst, lpChFont->lpTemplateName, 185 (LPWSTR)RT_DIALOG))) 186 { 187 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE); 188 return FALSE; 189 } 190 } else 191 { 192 hDlginst=COMDLG32_hInstance; 193 if (!(hResInfo = FindResourceW(hDlginst, chooseFontW, (LPWSTR)RT_DIALOG))) 194 { 195 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE); 196 return FALSE; 197 } 198 } 199 if (!(hDlgTmpl = LoadResource(hDlginst, hResInfo )) || 200 !(template = LockResource( hDlgTmpl ))) 201 { 202 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); 203 return FALSE; 204 } 205 } 206 if (TRACE_ON(commdlg)) 207 _dump_cf_flags(lpChFont->Flags); 208 209 if (lpChFont->Flags & CF_SELECTSCRIPT) 210 FIXME(": unimplemented flag (ignored)\n"); 211 212 return DialogBoxIndirectParamW(COMDLG32_hInstance, template, 213 lpChFont->hwndOwner, FormatCharDlgProcW, (LPARAM)lpChFont ); 214 } 215 216 /*********************************************************************** 217 * ChooseFontA (COMDLG32.@) 218 * 219 * See ChooseFontW. 220 */ 221 BOOL WINAPI ChooseFontA(LPCHOOSEFONTA lpChFont) 222 { 223 LPCVOID template; 224 HRSRC hResInfo; 225 HINSTANCE hDlginst; 226 HGLOBAL hDlgTmpl; 227 228 TRACE("(%p)\n", lpChFont); 229 230 if ( (lpChFont->Flags&CF_ENABLETEMPLATEHANDLE)!=0 ) 231 { 232 template=lpChFont->hInstance; 233 } else 234 { 235 if ( (lpChFont->Flags&CF_ENABLETEMPLATE)!=0 ) 236 { 237 hDlginst=lpChFont->hInstance; 238 if( !(hResInfo = FindResourceA(hDlginst, lpChFont->lpTemplateName, 239 (LPSTR)RT_DIALOG))) 240 { 241 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE); 242 return FALSE; 243 } 244 } else 245 { 246 hDlginst=COMDLG32_hInstance; 247 if (!(hResInfo = FindResourceW(hDlginst, chooseFontW, (LPWSTR)RT_DIALOG))) 248 { 249 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE); 250 return FALSE; 251 } 252 } 253 if (!(hDlgTmpl = LoadResource(hDlginst, hResInfo )) || 254 !(template = LockResource( hDlgTmpl ))) 255 { 256 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); 257 return FALSE; 258 } 259 } 260 if (TRACE_ON(commdlg)) 261 _dump_cf_flags(lpChFont->Flags); 262 if (lpChFont->Flags & CF_SELECTSCRIPT) 263 FIXME(": unimplemented flag (ignored)\n"); 264 265 return DialogBoxIndirectParamA(COMDLG32_hInstance, template, 266 lpChFont->hwndOwner, FormatCharDlgProcA, (LPARAM)lpChFont ); 267 } 268 269 #define TEXT_EXTRAS 4 270 #define TEXT_COLORS 16 271 272 static const COLORREF textcolors[TEXT_COLORS]= 273 { 274 0x00000000L,0x00000080L,0x00008000L,0x00008080L, 275 0x00800000L,0x00800080L,0x00808000L,0x00808080L, 276 0x00c0c0c0L,0x000000ffL,0x0000ff00L,0x0000ffffL, 277 0x00ff0000L,0x00ff00ffL,0x00ffff00L,0x00FFFFFFL 278 }; 279 280 /*********************************************************************** 281 * CFn_HookCallChk32 [internal] 282 */ 283 static BOOL CFn_HookCallChk32(const CHOOSEFONTW *lpcf) 284 { 285 if (lpcf) 286 if(lpcf->Flags & CF_ENABLEHOOK) 287 if (lpcf->lpfnHook) 288 return TRUE; 289 return FALSE; 290 } 291 292 /************************************************************************* 293 * AddFontFamily [internal] 294 */ 295 static INT AddFontFamily(const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM, 296 UINT nFontType, const CHOOSEFONTW *lpcf, HWND hwnd, LPCFn_ENUMSTRUCT e) 297 { 298 int i; 299 WORD w; 300 const LOGFONTW *lplf = &(lpElfex->elfLogFont); 301 302 TRACE("font=%s (nFontType=%d)\n", debugstr_w(lplf->lfFaceName), nFontType); 303 304 if (lpcf->Flags & CF_FIXEDPITCHONLY) 305 if (!(lplf->lfPitchAndFamily & FIXED_PITCH)) 306 return 1; 307 if (lpcf->Flags & CF_ANSIONLY) 308 if (lplf->lfCharSet != ANSI_CHARSET) 309 return 1; 310 if (lpcf->Flags & CF_TTONLY) 311 if (!(nFontType & TRUETYPE_FONTTYPE)) 312 return 1; 313 if (lpcf->Flags & CF_NOVERTFONTS) 314 if (lplf->lfFaceName[0] == '@') 315 return 1; 316 317 if (e) e->added++; 318 319 i=SendMessageW(hwnd, CB_FINDSTRINGEXACT, 0, (LPARAM)lplf->lfFaceName); 320 if (i == CB_ERR) { 321 i = SendMessageW(hwnd, CB_ADDSTRING, 0, (LPARAM)lplf->lfFaceName); 322 if( i != CB_ERR) { 323 /* store some important font information */ 324 w = (lplf->lfPitchAndFamily) << 8 | 325 (HIWORD(lpNTM->ntmTm.ntmFlags) & 0xff); 326 SendMessageW(hwnd, CB_SETITEMDATA, i, MAKELONG(nFontType,w)); 327 } 328 } 329 return 1; 330 } 331 332 /************************************************************************* 333 * FontFamilyEnumProc32 [internal] 334 */ 335 static INT WINAPI FontFamilyEnumProc(const ENUMLOGFONTEXW *lpElfex, 336 const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam) 337 { 338 LPCFn_ENUMSTRUCT e; 339 e=(LPCFn_ENUMSTRUCT)lParam; 340 return AddFontFamily( lpElfex, (const NEWTEXTMETRICEXW *) metrics, 341 dwFontType, e->lpcf32w, e->hWnd1, e); 342 } 343 344 /************************************************************************* 345 * SetFontStylesToCombo2 [internal] 346 * 347 * Fill font style information into combobox (without using font.c directly) 348 */ 349 static BOOL SetFontStylesToCombo2(HWND hwnd, HDC hdc, const LOGFONTW *lplf) 350 { 351 #define FSTYLES 4 352 struct FONTSTYLE 353 { 354 int italic; 355 int weight; 356 UINT resId; 357 }; 358 static const struct FONTSTYLE fontstyles[FSTYLES]={ 359 { 0, FW_NORMAL, IDS_FONT_REGULAR }, 360 { 1, FW_NORMAL, IDS_FONT_ITALIC }, 361 { 0, FW_BOLD, IDS_FONT_BOLD }, 362 { 1, FW_BOLD, IDS_FONT_BOLD_ITALIC } 363 }; 364 HFONT hf; 365 TEXTMETRICW tm; 366 int i,j; 367 LOGFONTW lf; 368 369 lf = *lplf; 370 371 for (i=0;i<FSTYLES;i++) 372 { 373 lf.lfItalic=fontstyles[i].italic; 374 lf.lfWeight=fontstyles[i].weight; 375 hf=CreateFontIndirectW(&lf); 376 hf=SelectObject(hdc,hf); 377 GetTextMetricsW(hdc,&tm); 378 hf=SelectObject(hdc,hf); 379 DeleteObject(hf); 380 /* font successful created ? */ 381 if (((fontstyles[i].weight == FW_NORMAL && tm.tmWeight <= FW_MEDIUM) || 382 (fontstyles[i].weight == FW_BOLD && tm.tmWeight > FW_MEDIUM)) && 383 ((tm.tmItalic != 0)==fontstyles[i].italic)) 384 { 385 WCHAR name[64]; 386 LoadStringW(COMDLG32_hInstance, fontstyles[i].resId, name, 64); 387 j=SendMessageW(hwnd,CB_ADDSTRING,0,(LPARAM)name ); 388 if (j==CB_ERR) return TRUE; 389 j=SendMessageW(hwnd, CB_SETITEMDATA, j, 390 MAKELONG(tm.tmWeight,fontstyles[i].italic)); 391 if (j==CB_ERR) return TRUE; 392 } 393 } 394 return FALSE; 395 } 396 397 /************************************************************************* 398 * AddFontSizeToCombo3 [internal] 399 */ 400 static BOOL AddFontSizeToCombo3(HWND hwnd, UINT h, const CHOOSEFONTW *lpcf) 401 { 402 int j; 403 WCHAR buffer[20]; 404 405 if ( (!(lpcf->Flags & CF_LIMITSIZE)) || 406 ((lpcf->Flags & CF_LIMITSIZE) && (h >= lpcf->nSizeMin) && (h <= lpcf->nSizeMax))) 407 { 408 sprintfW(buffer, fontsizefmtW, h); 409 j=SendMessageW(hwnd, CB_FINDSTRINGEXACT, -1, (LPARAM)buffer); 410 if (j==CB_ERR) 411 { 412 j=SendMessageW(hwnd, CB_INSERTSTRING, -1, (LPARAM)buffer); 413 if (j!=CB_ERR) j = SendMessageW(hwnd, CB_SETITEMDATA, j, h); 414 if (j==CB_ERR) return TRUE; 415 } 416 } 417 return FALSE; 418 } 419 420 /************************************************************************* 421 * SetFontSizesToCombo3 [internal] 422 */ 423 static BOOL SetFontSizesToCombo3(HWND hwnd, const CHOOSEFONTW *lpcf) 424 { 425 static const BYTE sizes[]={6,7,8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72}; 426 unsigned int i; 427 428 for (i = 0; i < sizeof(sizes)/sizeof(sizes[0]); i++) 429 if (AddFontSizeToCombo3(hwnd, sizes[i], lpcf)) return TRUE; 430 return FALSE; 431 } 432 433 /************************************************************************* 434 * CFn_GetDC [internal] 435 */ 436 static inline HDC CFn_GetDC(const CHOOSEFONTW *lpcf) 437 { 438 HDC ret = ((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC) ? 439 lpcf->hDC : 440 GetDC(0); 441 if(!ret) ERR("HDC failure!!!\n"); 442 return ret; 443 } 444 445 /************************************************************************* 446 * GetScreenDPI [internal] 447 */ 448 static inline int GetScreenDPI(void) 449 { 450 HDC hdc; 451 int result; 452 453 hdc = GetDC(0); 454 result = GetDeviceCaps(hdc, LOGPIXELSY); 455 ReleaseDC(0, hdc); 456 457 return result; 458 } 459 460 /************************************************************************* 461 * CFn_ReleaseDC [internal] 462 */ 463 static inline void CFn_ReleaseDC(const CHOOSEFONTW *lpcf, HDC hdc) 464 { 465 if(!((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC)) 466 ReleaseDC(0, hdc); 467 } 468 469 /*********************************************************************** 470 * AddFontStyle [internal] 471 */ 472 static INT AddFontStyle( const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM, 473 UINT nFontType, const CHOOSEFONTW *lpcf, HWND hcmb2, HWND hcmb3, HWND hDlg) 474 { 475 int i; 476 const LOGFONTW *lplf = &(lpElfex->elfLogFont); 477 HWND hcmb5; 478 HDC hdc; 479 480 TRACE("(nFontType=%d)\n",nFontType); 481 TRACE(" %s h=%d w=%d e=%d o=%d wg=%d i=%d u=%d s=%d" 482 " ch=%d op=%d cp=%d q=%d pf=%xh\n", 483 debugstr_w(lplf->lfFaceName),lplf->lfHeight,lplf->lfWidth, 484 lplf->lfEscapement,lplf->lfOrientation, 485 lplf->lfWeight,lplf->lfItalic,lplf->lfUnderline, 486 lplf->lfStrikeOut,lplf->lfCharSet, lplf->lfOutPrecision, 487 lplf->lfClipPrecision,lplf->lfQuality, lplf->lfPitchAndFamily); 488 if (nFontType & RASTER_FONTTYPE) 489 { 490 INT points; 491 points = MulDiv( lpNTM->ntmTm.tmHeight - lpNTM->ntmTm.tmInternalLeading, 492 72, GetScreenDPI()); 493 if (AddFontSizeToCombo3(hcmb3, points, lpcf)) 494 return 0; 495 } else if (SetFontSizesToCombo3(hcmb3, lpcf)) return 0; 496 497 if (!SendMessageW(hcmb2, CB_GETCOUNT, 0, 0)) 498 { 499 BOOL res; 500 if(!(hdc = CFn_GetDC(lpcf))) return 0; 501 res = SetFontStylesToCombo2(hcmb2,hdc,lplf); 502 CFn_ReleaseDC(lpcf, hdc); 503 if (res) 504 return 0; 505 } 506 if (!( hcmb5 = GetDlgItem(hDlg, cmb5))) return 1; 507 i = SendMessageW( hcmb5, CB_FINDSTRINGEXACT, 0, 508 (LPARAM)lpElfex->elfScript); 509 if( i == CB_ERR) { 510 i = SendMessageW( hcmb5, CB_ADDSTRING, 0, 511 (LPARAM)lpElfex->elfScript); 512 if( i != CB_ERR) 513 SendMessageW( hcmb5, CB_SETITEMDATA, i, lplf->lfCharSet); 514 } 515 return 1 ; 516 } 517 518 static void CFn_FitFontSize( HWND hDlg, int points) 519 { 520 int i,n; 521 522 /* look for fitting font size in combobox3 */ 523 n=SendDlgItemMessageW(hDlg, cmb3, CB_GETCOUNT, 0, 0); 524 for (i=0;i<n;i++) 525 { 526 if (points == (int)SendDlgItemMessageW 527 (hDlg,cmb3, CB_GETITEMDATA,i,0)) 528 { 529 SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,i,0); 530 SendMessageW(hDlg, WM_COMMAND, 531 MAKEWPARAM(cmb3, CBN_SELCHANGE), 532 (LPARAM)GetDlgItem(hDlg,cmb3)); 533 return; 534 } 535 } 536 537 /* no default matching size, set text manually */ 538 SetDlgItemInt(hDlg, cmb3, points, TRUE); 539 } 540 541 static BOOL CFn_FitFontStyle( HWND hDlg, LONG packedstyle ) 542 { 543 LONG id; 544 int i; 545 BOOL ret = FALSE; 546 /* look for fitting font style in combobox2 */ 547 for (i=0;i<TEXT_EXTRAS;i++) 548 { 549 id = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0); 550 if (packedstyle == id) 551 { 552 SendDlgItemMessageW(hDlg, cmb2, CB_SETCURSEL, i, 0); 553 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE), 554 (LPARAM)GetDlgItem(hDlg,cmb2)); 555 ret = TRUE; 556 break; 557 } 558 } 559 return ret; 560 } 561 562 563 static BOOL CFn_FitCharSet( HWND hDlg, int charset ) 564 { 565 int i,n,cs; 566 /* look for fitting char set in combobox5 */ 567 n=SendDlgItemMessageW(hDlg, cmb5, CB_GETCOUNT, 0, 0); 568 for (i=0;i<n;i++) 569 { 570 cs =SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0); 571 if (charset == cs) 572 { 573 SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, i, 0); 574 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE), 575 (LPARAM)GetDlgItem(hDlg,cmb2)); 576 return TRUE; 577 } 578 } 579 /* no charset fits: select the first one in the list */ 580 SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, 0, 0); 581 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE), 582 (LPARAM)GetDlgItem(hDlg,cmb2)); 583 return FALSE; 584 } 585 586 /*********************************************************************** 587 * FontStyleEnumProc32 [internal] 588 */ 589 static INT WINAPI FontStyleEnumProc( const ENUMLOGFONTEXW *lpElfex, 590 const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam ) 591 { 592 LPCFn_ENUMSTRUCT s=(LPCFn_ENUMSTRUCT)lParam; 593 HWND hcmb2=s->hWnd1; 594 HWND hcmb3=s->hWnd2; 595 HWND hDlg=GetParent(hcmb3); 596 return AddFontStyle( lpElfex, (const NEWTEXTMETRICEXW *) metrics, 597 dwFontType, s->lpcf32w, hcmb2, hcmb3, hDlg); 598 } 599 600 /*********************************************************************** 601 * CFn_WMInitDialog [internal] 602 */ 603 static LRESULT CFn_WMInitDialog(HWND hDlg, LPARAM lParam, LPCHOOSEFONTW lpcf) 604 { 605 HDC hdc; 606 int i,j; 607 BOOL init = FALSE; 608 long pstyle; 609 CFn_ENUMSTRUCT s; 610 LPLOGFONTW lpxx; 611 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT)); 612 static const WCHAR strColorName[] = {'[','c','o','l','o','r',' ','n','a','m','e',']',0}; 613 614 SetPropW(hDlg, strWineFontData, lpcf); 615 lpxx=lpcf->lpLogFont; 616 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam); 617 618 if (lpcf->lStructSize != sizeof(CHOOSEFONTW)) 619 { 620 ERR("structure size failure!!!\n"); 621 EndDialog (hDlg, 0); 622 return FALSE; 623 } 624 if (!himlTT) 625 himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38), 626 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0); 627 628 /* Set effect flags */ 629 if((lpcf->Flags & CF_EFFECTS) && (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)) 630 { 631 if(lpxx->lfUnderline) 632 CheckDlgButton(hDlg, chx2, TRUE); 633 if(lpxx->lfStrikeOut) 634 CheckDlgButton(hDlg, chx1, TRUE); 635 } 636 637 if (!(lpcf->Flags & CF_SHOWHELP) || !IsWindow(lpcf->hwndOwner)) 638 ShowWindow(GetDlgItem(hDlg,pshHelp),SW_HIDE); 639 if (!(lpcf->Flags & CF_APPLY)) 640 ShowWindow(GetDlgItem(hDlg,psh3),SW_HIDE); 641 if (lpcf->Flags & CF_NOSCRIPTSEL) 642 EnableWindow(GetDlgItem(hDlg,cmb5),FALSE); 643 if (lpcf->Flags & CF_EFFECTS) 644 { 645 for (i=0;i<TEXT_COLORS;i++) 646 { 647 WCHAR name[30]; 648 649 if( LoadStringW(COMDLG32_hInstance, IDS_COLOR_BLACK+i, name, 650 sizeof(name)/sizeof(*name) )==0 ) 651 { 652 memcpy(name, strColorName, sizeof(strColorName)); 653 } 654 j=SendDlgItemMessageW(hDlg, cmb4, CB_ADDSTRING, 0, (LPARAM)name); 655 SendDlgItemMessageW(hDlg, cmb4, CB_SETITEMDATA, j, textcolors[i]); 656 /* look for a fitting value in color combobox */ 657 if (textcolors[i]==lpcf->rgbColors) 658 SendDlgItemMessageW(hDlg,cmb4, CB_SETCURSEL,j,0); 659 } 660 } 661 else 662 { 663 ShowWindow(GetDlgItem(hDlg,cmb4),SW_HIDE); 664 ShowWindow(GetDlgItem(hDlg,chx1),SW_HIDE); 665 ShowWindow(GetDlgItem(hDlg,chx2),SW_HIDE); 666 ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE); 667 ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE); 668 } 669 if(!(hdc = CFn_GetDC(lpcf))) 670 { 671 EndDialog (hDlg, 0); 672 return FALSE; 673 } 674 s.hWnd1=GetDlgItem(hDlg,cmb1); 675 s.lpcf32w=lpcf; 676 do { 677 LOGFONTW elf; 678 s.added = 0; 679 elf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */ 680 elf.lfPitchAndFamily = 0; 681 elf.lfFaceName[0] = '\0'; /* enum all fonts */ 682 if (!EnumFontFamiliesExW(hdc, &elf, (FONTENUMPROCW)FontFamilyEnumProc, (LPARAM)&s, 0)) 683 { 684 TRACE("EnumFontFamiliesEx returns 0\n"); 685 break; 686 } 687 if (s.added) break; 688 if (lpcf->Flags & CF_FIXEDPITCHONLY) { 689 FIXME("No font found with fixed pitch only, dropping flag.\n"); 690 lpcf->Flags &= ~CF_FIXEDPITCHONLY; 691 continue; 692 } 693 if (lpcf->Flags & CF_TTONLY) { 694 FIXME("No font found with truetype only, dropping flag.\n"); 695 lpcf->Flags &= ~CF_TTONLY; 696 continue; 697 } 698 break; 699 } while (1); 700 701 702 if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT) 703 { 704 /* look for fitting font name in combobox1 */ 705 j=SendDlgItemMessageW(hDlg,cmb1,CB_FINDSTRING,-1,(LPARAM)lpxx->lfFaceName); 706 if (j!=CB_ERR) 707 { 708 INT height = lpxx->lfHeight < 0 ? -lpxx->lfHeight : 709 lpxx->lfHeight; 710 INT points; 711 int charset = lpxx->lfCharSet; 712 points = MulDiv( height, 72, GetScreenDPI()); 713 pstyle = MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD: 714 FW_NORMAL,lpxx->lfItalic !=0); 715 SendDlgItemMessageW(hDlg, cmb1, CB_SETCURSEL, j, 0); 716 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE), 717 (LPARAM)GetDlgItem(hDlg,cmb1)); 718 init = TRUE; 719 /* look for fitting font style in combobox2 */ 720 CFn_FitFontStyle(hDlg, pstyle); 721 /* look for fitting font size in combobox3 */ 722 CFn_FitFontSize(hDlg, points); 723 CFn_FitCharSet( hDlg, charset ); 724 } 725 } 726 if (!init) 727 { 728 SendDlgItemMessageW(hDlg,cmb1,CB_SETCURSEL,0,0); 729 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE), 730 (LPARAM)GetDlgItem(hDlg,cmb1)); 731 SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,0,0); 732 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE), 733 (LPARAM)GetDlgItem(hDlg,cmb1)); 734 SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,0,0); 735 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb3, CBN_SELCHANGE), 736 (LPARAM)GetDlgItem(hDlg,cmb3)); 737 SendDlgItemMessageW(hDlg,cmb5,CB_SETCURSEL,0,0); 738 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE), 739 (LPARAM)GetDlgItem(hDlg,cmb5)); 740 } 741 /* limit text length user can type in as font size */ 742 SendDlgItemMessageW(hDlg, cmb3, CB_LIMITTEXT, 5, 0); 743 744 if ((lpcf->Flags & CF_USESTYLE) && lpcf->lpszStyle) 745 { 746 j=SendDlgItemMessageW(hDlg,cmb2,CB_FINDSTRING,-1,(LPARAM)lpcf->lpszStyle); 747 if (j!=CB_ERR) 748 { 749 j=SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,j,0); 750 SendMessageW(hDlg,WM_COMMAND,cmb2, 751 MAKELONG(LOWORD(GetDlgItem(hDlg,cmb2)),CBN_SELCHANGE)); 752 } 753 } 754 CFn_ReleaseDC(lpcf, hdc); 755 SetCursor(hcursor); 756 return TRUE; 757 } 758 759 760 /*********************************************************************** 761 * CFn_WMMeasureItem [internal] 762 */ 763 static LRESULT CFn_WMMeasureItem(HWND hDlg, LPARAM lParam) 764 { 765 HDC hdc; 766 HFONT hfontprev; 767 TEXTMETRICW tm; 768 LPMEASUREITEMSTRUCT lpmi=(LPMEASUREITEMSTRUCT)lParam; 769 INT height = 0, cx; 770 771 if (!himlTT) 772 himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38), 773 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0); 774 ImageList_GetIconSize( himlTT, &cx, &height); 775 lpmi->itemHeight = height + 2; 776 /* use MAX of bitmap height and tm.tmHeight .*/ 777 hdc=GetDC(hDlg); 778 if(!hdc) return 0; 779 hfontprev = SelectObject( hdc, (HFONT)SendMessageW( hDlg, WM_GETFONT, 0, 0 )); 780 GetTextMetricsW(hdc, &tm); 781 if( tm.tmHeight > lpmi->itemHeight) lpmi->itemHeight = tm.tmHeight; 782 SelectObject(hdc, hfontprev); 783 ReleaseDC(hDlg, hdc); 784 return 0; 785 } 786 787 788 /*********************************************************************** 789 * CFn_WMDrawItem [internal] 790 */ 791 static LRESULT CFn_WMDrawItem(LPARAM lParam) 792 { 793 HBRUSH hBrush; 794 WCHAR buffer[40]; 795 COLORREF cr, oldText=0, oldBk=0; 796 RECT rect; 797 int nFontType; 798 int cx, cy, idx; 799 LPDRAWITEMSTRUCT lpdi = (LPDRAWITEMSTRUCT)lParam; 800 801 if (lpdi->itemID == (UINT)-1) /* got no items */ 802 DrawFocusRect(lpdi->hDC, &lpdi->rcItem); 803 else 804 { 805 if (lpdi->CtlType == ODT_COMBOBOX) 806 { 807 if (lpdi->itemState & ODS_SELECTED) 808 { 809 hBrush=GetSysColorBrush(COLOR_HIGHLIGHT); 810 oldText=SetTextColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); 811 oldBk=SetBkColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHT)); 812 } else 813 { 814 hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH)); 815 SelectObject(lpdi->hDC, hBrush); 816 } 817 FillRect(lpdi->hDC, &lpdi->rcItem, hBrush); 818 } 819 else 820 return TRUE; /* this should never happen */ 821 822 rect=lpdi->rcItem; 823 switch (lpdi->CtlID) 824 { 825 case cmb1: 826 /* TRACE(commdlg,"WM_Drawitem cmb1\n"); */ 827 ImageList_GetIconSize( himlTT, &cx, &cy); 828 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID, 829 (LPARAM)buffer); 830 TextOutW(lpdi->hDC, lpdi->rcItem.left + cx + 4, 831 lpdi->rcItem.top, buffer, lstrlenW(buffer)); 832 nFontType = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L); 833 idx = -1; 834 if (nFontType & TRUETYPE_FONTTYPE) { 835 idx = 0; /* picture: TT */ 836 if( nFontType & NTM_TT_OPENTYPE) 837 idx = 2; /* picture: O */ 838 } else if( nFontType & NTM_PS_OPENTYPE) 839 idx = 3; /* picture: O+ps */ 840 else if( nFontType & NTM_TYPE1) 841 idx = 4; /* picture: a */ 842 else if( nFontType & DEVICE_FONTTYPE) 843 idx = 1; /* picture: printer */ 844 if( idx >= 0) 845 ImageList_Draw( himlTT, idx, lpdi->hDC, lpdi->rcItem.left, 846 (lpdi->rcItem.top + lpdi->rcItem.bottom - cy) / 2, ILD_TRANSPARENT); 847 break; 848 case cmb2: 849 case cmb3: 850 /* TRACE(commdlg,"WM_DRAWITEN cmb2,cmb3\n"); */ 851 case cmb5: 852 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID, 853 (LPARAM)buffer); 854 TextOutW(lpdi->hDC, lpdi->rcItem.left, 855 lpdi->rcItem.top, buffer, lstrlenW(buffer)); 856 break; 857 858 case cmb4: 859 /* TRACE(commdlg,"WM_DRAWITEM cmb4 (=COLOR)\n"); */ 860 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID, 861 (LPARAM)buffer); 862 TextOutW(lpdi->hDC, lpdi->rcItem.left + 25+5, 863 lpdi->rcItem.top, buffer, lstrlenW(buffer)); 864 cr = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L); 865 hBrush = CreateSolidBrush(cr); 866 if (hBrush) 867 { 868 hBrush = SelectObject (lpdi->hDC, hBrush) ; 869 rect.right=rect.left+25; 870 rect.top++; 871 rect.left+=5; 872 rect.bottom--; 873 Rectangle( lpdi->hDC, rect.left, rect.top, 874 rect.right, rect.bottom ); 875 DeleteObject( SelectObject (lpdi->hDC, hBrush)) ; 876 } 877 rect=lpdi->rcItem; 878 rect.left+=25+5; 879 break; 880 881 default: 882 return TRUE; /* this should never happen */ 883 } 884 if (lpdi->itemState & ODS_SELECTED) 885 { 886 SetTextColor(lpdi->hDC, oldText); 887 SetBkColor(lpdi->hDC, oldBk); 888 } 889 } 890 return TRUE; 891 } 892 893 static INT get_dialog_font_point_size(HWND hDlg, CHOOSEFONTW *cf) 894 { 895 BOOL invalid_size = FALSE; 896 INT i, size; 897 898 i = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0); 899 if (i != CB_ERR) 900 size = LOWORD(SendDlgItemMessageW(hDlg, cmb3, CB_GETITEMDATA , i, 0)); 901 else 902 { 903 WCHAR buffW[8], *endptrW; 904 905 GetDlgItemTextW(hDlg, cmb3, buffW, sizeof(buffW)/sizeof(*buffW)); 906 size = strtolW(buffW, &endptrW, 10); 907 invalid_size = size == 0 && *endptrW; 908 909 if (size == 0) 910 size = 10; 911 } 912 913 cf->iPointSize = 10 * size; 914 cf->lpLogFont->lfHeight = -MulDiv(cf->iPointSize, GetScreenDPI(), 720); 915 return invalid_size ? -1 : size; 916 } 917 918 /*********************************************************************** 919 * CFn_WMCommand [internal] 920 */ 921 static LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcf) 922 { 923 int i; 924 long l; 925 HDC hdc; 926 BOOL cmb_selected_by_edit = FALSE; 927 928 if (!lpcf) return FALSE; 929 930 if(HIWORD(wParam) == CBN_EDITCHANGE) 931 { 932 int idx; 933 WCHAR str_edit[256], str_cmb[256]; 934 int cmb = LOWORD(wParam); 935 936 GetDlgItemTextW(hDlg, cmb, str_edit, sizeof(str_edit) / sizeof(str_edit[0])); 937 idx = SendDlgItemMessageW(hDlg, cmb, CB_FINDSTRING, -1, (LPARAM)str_edit); 938 if(idx != -1) 939 { 940 SendDlgItemMessageW(hDlg, cmb, CB_GETLBTEXT, idx, (LPARAM)str_cmb); 941 942 /* Select listbox entry only if we have an exact match */ 943 if(lstrcmpiW(str_edit, str_cmb) == 0) 944 { 945 SendDlgItemMessageW(hDlg, cmb, CB_SETCURSEL, idx, 0); 946 SendDlgItemMessageW(hDlg, cmb, CB_SETEDITSEL, 0, -1); /* Remove edit field selection */ 947 cmb_selected_by_edit = TRUE; 948 } 949 } 950 } 951 952 TRACE("WM_COMMAND wParam=%08X lParam=%08lX\n", (LONG)wParam, lParam); 953 switch (LOWORD(wParam)) 954 { 955 case cmb1: 956 if (HIWORD(wParam) == CBN_SELCHANGE || cmb_selected_by_edit) 957 { 958 INT pointsize; /* save current pointsize */ 959 LONG pstyle; /* save current style */ 960 int charset; 961 int idx; 962 if(!(hdc = CFn_GetDC(lpcf))) 963 { 964 EndDialog (hDlg, 0); 965 return TRUE; 966 } 967 idx = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0); 968 pointsize = (int)SendDlgItemMessageW( hDlg, cmb3, CB_GETITEMDATA, 969 idx, 0); 970 idx = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0); 971 pstyle = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, idx, 0); 972 idx = SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0); 973 charset = SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, idx, 0); 974 975 SendDlgItemMessageW(hDlg, cmb2, CB_RESETCONTENT, 0, 0); 976 SendDlgItemMessageW(hDlg, cmb3, CB_RESETCONTENT, 0, 0); 977 SendDlgItemMessageW(hDlg, cmb5, CB_RESETCONTENT, 0, 0); 978 i=SendDlgItemMessageW(hDlg, cmb1, CB_GETCURSEL, 0, 0); 979 if (i!=CB_ERR) 980 { 981 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT)); 982 CFn_ENUMSTRUCT s; 983 LOGFONTW enumlf; 984 SendDlgItemMessageW(hDlg, cmb1, CB_GETLBTEXT, i, 985 (LPARAM)enumlf.lfFaceName); 986 TRACE("WM_COMMAND/cmb1 =>%s\n", debugstr_w(enumlf.lfFaceName)); 987 s.hWnd1=GetDlgItem(hDlg, cmb2); 988 s.hWnd2=GetDlgItem(hDlg, cmb3); 989 s.lpcf32w=lpcf; 990 enumlf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */ 991 enumlf.lfPitchAndFamily = 0; 992 EnumFontFamiliesExW(hdc, &enumlf, 993 (FONTENUMPROCW)FontStyleEnumProc, (LPARAM)&s, 0); 994 CFn_FitFontStyle(hDlg, pstyle); 995 if( pointsize != CB_ERR) CFn_FitFontSize(hDlg, pointsize); 996 if( charset != CB_ERR) CFn_FitCharSet( hDlg, charset ); 997 SetCursor(hcursor); 998 } 999 CFn_ReleaseDC(lpcf, hdc); 1000 } 1001 break; 1002 case chx1: 1003 case chx2: 1004 case cmb2: 1005 case cmb3: 1006 case cmb5: 1007 if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == BN_CLICKED || cmb_selected_by_edit) 1008 { 1009 WCHAR str[256]; 1010 WINDOWINFO wininfo; 1011 LPLOGFONTW lpxx=lpcf->lpLogFont; 1012 1013 TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam); 1014 1015 /* face name */ 1016 i=SendDlgItemMessageW(hDlg,cmb1,CB_GETCURSEL,0,0); 1017 if (i==CB_ERR) 1018 GetDlgItemTextW( hDlg, cmb1, str, sizeof(str)/sizeof(str[0]) ); 1019 else 1020 { 1021 SendDlgItemMessageW(hDlg,cmb1,CB_GETLBTEXT,i, 1022 (LPARAM)str); 1023 l=SendDlgItemMessageW(hDlg,cmb1,CB_GETITEMDATA,i,0); 1024 lpcf->nFontType = LOWORD(l); 1025 /* FIXME: lpcf->nFontType |= .... SIMULATED_FONTTYPE and so */ 1026 /* same value reported to the EnumFonts 1027 call back with the extra FONTTYPE_... bits added */ 1028 lpxx->lfPitchAndFamily = HIWORD(l) >> 8; 1029 } 1030 lstrcpynW(lpxx->lfFaceName, str, sizeof(lpxx->lfFaceName)/sizeof(lpxx->lfFaceName[0])); 1031 1032 /* style */ 1033 i=SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0); 1034 if (i!=CB_ERR) 1035 { 1036 l=SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0); 1037 if (0!=(lpxx->lfItalic=HIWORD(l))) 1038 lpcf->nFontType |= ITALIC_FONTTYPE; 1039 if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM) 1040 lpcf->nFontType |= BOLD_FONTTYPE; 1041 } 1042 1043 /* size */ 1044 get_dialog_font_point_size(hDlg, lpcf); 1045 1046 /* charset */ 1047 i=SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0); 1048 if (i!=CB_ERR) 1049 lpxx->lfCharSet=SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0); 1050 else 1051 lpxx->lfCharSet = DEFAULT_CHARSET; 1052 lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1); 1053 lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2); 1054 lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0; 1055 lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS; 1056 lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS; 1057 lpxx->lfQuality=DEFAULT_QUALITY; 1058 1059 wininfo.cbSize=sizeof(wininfo); 1060 1061 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) ) 1062 { 1063 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2); 1064 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE ); 1065 } 1066 } 1067 break; 1068 1069 case cmb4: 1070 i=SendDlgItemMessageW(hDlg, cmb4, CB_GETCURSEL, 0, 0); 1071 if (i!=CB_ERR) 1072 { 1073 WINDOWINFO wininfo; 1074 1075 lpcf->rgbColors = SendDlgItemMessageW(hDlg, cmb4, CB_GETITEMDATA, i, 0); 1076 wininfo.cbSize=sizeof(wininfo); 1077 1078 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) ) 1079 { 1080 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2); 1081 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE ); 1082 } 1083 } 1084 break; 1085 1086 case psh15: 1087 i=RegisterWindowMessageW( HELPMSGSTRINGW ); 1088 if (lpcf->hwndOwner) 1089 SendMessageW(lpcf->hwndOwner, i, 0, (LPARAM)GetPropW(hDlg, strWineFontData)); 1090 break; 1091 1092 case IDOK: 1093 { 1094 WCHAR msgW[80]; 1095 INT pointsize; 1096 1097 pointsize = get_dialog_font_point_size(hDlg, lpcf); 1098 if (pointsize == -1) 1099 { 1100 LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE_INPUT, msgW, sizeof(msgW)/sizeof(*msgW)); 1101 MessageBoxW(hDlg, msgW, NULL, MB_OK | MB_ICONINFORMATION); 1102 return TRUE; 1103 } 1104 1105 if ( (!(lpcf->Flags & CF_LIMITSIZE)) || 1106 ( (lpcf->Flags & CF_LIMITSIZE) && 1107 (lpcf->iPointSize >= 10 * lpcf->nSizeMin) && 1108 (lpcf->iPointSize <= 10 * lpcf->nSizeMax))) 1109 EndDialog(hDlg, TRUE); 1110 else 1111 { 1112 WCHAR format[80]; 1113 DWORD_PTR args[2]; 1114 LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE, format, sizeof(format)/sizeof(WCHAR)); 1115 args[0] = lpcf->nSizeMin; 1116 args[1] = lpcf->nSizeMax; 1117 FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY, 1118 format, 0, 0, msgW, sizeof(msgW)/sizeof(*msgW), 1119 (__ms_va_list*)args); 1120 MessageBoxW(hDlg, msgW, NULL, MB_OK); 1121 } 1122 return(TRUE); 1123 } 1124 case IDCANCEL: 1125 EndDialog(hDlg, FALSE); 1126 return(TRUE); 1127 } 1128 return(FALSE); 1129 } 1130 1131 static LRESULT CFn_WMDestroy(HWND hwnd, LPCHOOSEFONTW lpcfw) 1132 { 1133 LPCHOOSEFONTA lpcfa; 1134 LPSTR lpszStyle; 1135 LPLOGFONTA lpLogFonta; 1136 int len; 1137 1138 if (!lpcfw) return FALSE; 1139 1140 lpcfa = GetPropW(hwnd, strWineFontData_a); 1141 lpLogFonta = lpcfa->lpLogFont; 1142 lpszStyle = lpcfa->lpszStyle; 1143 memcpy(lpcfa, lpcfw, sizeof(CHOOSEFONTA)); 1144 lpcfa->lpLogFont = lpLogFonta; 1145 lpcfa->lpszStyle = lpszStyle; 1146 memcpy(lpcfa->lpLogFont, lpcfw->lpLogFont, sizeof(LOGFONTA)); 1147 WideCharToMultiByte(CP_ACP, 0, lpcfw->lpLogFont->lfFaceName, 1148 LF_FACESIZE, lpcfa->lpLogFont->lfFaceName, LF_FACESIZE, 0, 0); 1149 1150 if((lpcfw->Flags & CF_USESTYLE) && lpcfw->lpszStyle) { 1151 len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, 0, 0, 0); 1152 WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, lpcfa->lpszStyle, len, 0, 0); 1153 HeapFree(GetProcessHeap(), 0, lpcfw->lpszStyle); 1154 } 1155 1156 HeapFree(GetProcessHeap(), 0, lpcfw->lpLogFont); 1157 HeapFree(GetProcessHeap(), 0, lpcfw); 1158 SetPropW(hwnd, strWineFontData, 0); 1159 1160 return TRUE; 1161 } 1162 1163 static LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, const CHOOSEFONTW *lpcf) 1164 { 1165 WINDOWINFO info; 1166 1167 if (!lpcf) return FALSE; 1168 1169 info.cbSize=sizeof(info); 1170 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &info ) ) 1171 { 1172 PAINTSTRUCT ps; 1173 HDC hdc; 1174 HFONT hOrigFont; 1175 LOGFONTW lf = *(lpcf->lpLogFont); 1176 1177 MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2); 1178 hdc = BeginPaint( hDlg, &ps ); 1179 1180 TRACE("erase %d, rect=%s\n", ps.fErase, wine_dbgstr_rect(&ps.rcPaint)); 1181 1182 /* Paint frame */ 1183 DrawEdge( hdc, &info.rcWindow, EDGE_SUNKEN, BF_RECT|BF_ADJUST ); 1184 1185 /* Draw the sample text itself */ 1186 hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) ); 1187 SetTextColor( hdc, lpcf->rgbColors ); 1188 1189 DrawTextW( hdc, 1190 sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]], 1191 -1, &info.rcWindow, DT_CENTER|DT_VCENTER|DT_SINGLELINE ); 1192 1193 DeleteObject(SelectObject( hdc, hOrigFont )); 1194 EndPaint( hDlg, &ps ); 1195 } 1196 return FALSE; 1197 } 1198 1199 /*********************************************************************** 1200 * FormatCharDlgProcA [internal] 1201 */ 1202 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 1203 { 1204 LPCHOOSEFONTW lpcfw; 1205 LPCHOOSEFONTA lpcfa; 1206 INT_PTR res = FALSE; 1207 int len; 1208 1209 if (uMsg!=WM_INITDIALOG) { 1210 lpcfw = GetPropW(hDlg, strWineFontData); 1211 if (lpcfw && CFn_HookCallChk32(lpcfw)) 1212 res=CallWindowProcA((WNDPROC)lpcfw->lpfnHook, hDlg, uMsg, wParam, lParam); 1213 if (res) 1214 return res; 1215 } else { 1216 lpcfa=(LPCHOOSEFONTA)lParam; 1217 SetPropW(hDlg, strWineFontData_a, (HANDLE)lParam); 1218 1219 lpcfw = HeapAlloc(GetProcessHeap(), 0, sizeof(CHOOSEFONTW)); 1220 memcpy(lpcfw, lpcfa, sizeof(CHOOSEFONTA)); 1221 lpcfw->lpLogFont = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGFONTW)); 1222 memcpy(lpcfw->lpLogFont, lpcfa->lpLogFont, sizeof(LOGFONTA)); 1223 MultiByteToWideChar(CP_ACP, 0, lpcfa->lpLogFont->lfFaceName, 1224 LF_FACESIZE, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE); 1225 1226 if((lpcfa->Flags & CF_USESTYLE) && lpcfa->lpszStyle) { 1227 len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, NULL, 0); 1228 lpcfw->lpszStyle = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); 1229 MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len); 1230 } 1231 1232 if (!CFn_WMInitDialog(hDlg, lParam, lpcfw)) 1233 { 1234 TRACE("CFn_WMInitDialog returned FALSE\n"); 1235 return FALSE; 1236 } 1237 if (CFn_HookCallChk32(lpcfw)) 1238 return CallWindowProcA((WNDPROC)lpcfa->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam); 1239 } 1240 switch (uMsg) 1241 { 1242 case WM_MEASUREITEM: 1243 return CFn_WMMeasureItem(hDlg,lParam); 1244 case WM_DRAWITEM: 1245 return CFn_WMDrawItem(lParam); 1246 case WM_COMMAND: 1247 return CFn_WMCommand(hDlg, wParam, lParam, lpcfw); 1248 case WM_DESTROY: 1249 return CFn_WMDestroy(hDlg, lpcfw); 1250 case WM_CHOOSEFONT_GETLOGFONT: 1251 { 1252 LOGFONTA *logfont = (LOGFONTA *)lParam; 1253 TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam); 1254 memcpy( logfont, lpcfw->lpLogFont, FIELD_OFFSET( LOGFONTA, lfFaceName )); 1255 WideCharToMultiByte( CP_ACP, 0, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE, 1256 logfont->lfFaceName, LF_FACESIZE, NULL, NULL ); 1257 break; 1258 } 1259 case WM_PAINT: 1260 return CFn_WMPaint(hDlg, wParam, lParam, lpcfw); 1261 } 1262 return res; 1263 } 1264 1265 /*********************************************************************** 1266 * FormatCharDlgProcW [internal] 1267 */ 1268 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 1269 { 1270 LPCHOOSEFONTW lpcf; 1271 INT_PTR res = FALSE; 1272 1273 if (uMsg!=WM_INITDIALOG) 1274 { 1275 lpcf= GetPropW(hDlg, strWineFontData); 1276 if (lpcf && CFn_HookCallChk32(lpcf)) 1277 res=CallWindowProcW((WNDPROC)lpcf->lpfnHook, hDlg, uMsg, wParam, lParam); 1278 if (res) 1279 return res; 1280 } 1281 else 1282 { 1283 lpcf=(LPCHOOSEFONTW)lParam; 1284 if (!CFn_WMInitDialog(hDlg, lParam, lpcf)) 1285 { 1286 TRACE("CFn_WMInitDialog returned FALSE\n"); 1287 return FALSE; 1288 } 1289 if (CFn_HookCallChk32(lpcf)) 1290 return CallWindowProcW((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam); 1291 } 1292 switch (uMsg) 1293 { 1294 case WM_MEASUREITEM: 1295 return CFn_WMMeasureItem(hDlg, lParam); 1296 case WM_DRAWITEM: 1297 return CFn_WMDrawItem(lParam); 1298 case WM_COMMAND: 1299 return CFn_WMCommand(hDlg, wParam, lParam, lpcf); 1300 case WM_DESTROY: 1301 return TRUE; 1302 case WM_CHOOSEFONT_GETLOGFONT: 1303 TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam); 1304 memcpy( (LOGFONTW *)lParam, lpcf->lpLogFont, sizeof(LOGFONTW) ); 1305 break; 1306 case WM_PAINT: 1307 return CFn_WMPaint(hDlg, wParam, lParam, lpcf); 1308 } 1309 return res; 1310 } 1311