现在的位置: 首页 > 综合 > 正文

EnumFontFamilies

2013年10月13日 ⁄ 综合 ⁄ 共 3848字 ⁄ 字号 评论关闭

  PC的文字游戏一般在设置界面中有选择字体的地方,一般来说是从系统字体中筛选出合适的字体,很少会给玩家字体对话框来选择的。这个筛选是靠EnumFontFamilies。

 

  int EnumFontFamilies(

    HDC hdc,                        // handle to device control
    LPCTSTR lpszFamily,             // pointer to family-name string
    FONTENUMPROC lpEnumFontFamProc, // pointer to callback function
    LPARAM lParam                   // address of application-supplied data 
   );

 

 里面主要的参数是FONTENUMPROC lpEnumFontFamProc,定义如下:

 

  int CALLBACK EnumFontFamProc(

    ENUMLOGFONT FAR *lpelf,   // pointer to logical-font data
    NEWTEXTMETRIC FAR *lpntm, // pointer to physical-font data
    int FontType,             // type of font
    LPARAM lParam             // address of application-defined data 
   );

 

  第一个参数指向ENUMLOGFONT数据,

typedef struct tagENUMLOGFONT { // elf 
    LOGFONT elfLogFont;
    BCHAR    elfFullName[LF_FULLFACESIZE];
    BCHAR    elfStyle[LF_FACESIZE];
} ENUMLOGFONT;

 

  其实也就是一个LOGFONT + 字体名,所以调试的时候可以在内存跟随这个结构来看字体名。

 LOGFONT应该很熟了,如下:

 

typedef struct tagLOGFONT { // lf 
   LONG lfHeight;
   LONG lfWidth;
   LONG lfEscapement;
   LONG lfOrientation;
   LONG lfWeight;                   // 10
   BYTE lfItalic;                   // 14
   BYTE lfUnderline;
   BYTE lfStrikeOut;
   BYTE lfCharSet;                  // 17 一般判断这里
   BYTE lfOutPrecision;             // 18
   BYTE lfClipPrecision;
   BYTE lfQuality;
   BYTE lfPitchAndFamily;
   TCHAR lfFaceName[LF_FACESIZE];   // 1c
} LOGFONT;

 

  第二个指向 NEWTEXTMETRIC,结构如下:

typedef struct tagNEWTEXTMETRIC { // ntm 
    LONG   tmHeight;
    LONG   tmAscent;
    LONG   tmDescent;
    LONG   tmInternalLeading;
    LONG   tmExternalLeading;
    LONG   tmAveCharWidth;
    LONG   tmMaxCharWidth;
    LONG   tmWeight;
    LONG   tmOverhang;
    LONG   tmDigitizedAspectX;
    LONG   tmDigitizedAspectY;
    BCHAR  tmFirstChar;
    BCHAR  tmLastChar;
    BCHAR  tmDefaultChar;
    BCHAR  tmBreakChar;
    BYTE   tmItalic;

    BYTE   tmUnderlined;
    BYTE   tmStruckOut;
    BYTE   tmPitchAndFamily;
    BYTE   tmCharSet;
    DWORD  ntmFlags;
    UINT   ntmSizeEM;
    UINT   ntmCellHeight;
    UINT   ntmAvgWidth;
} NEWTEXTMETRIC;

  字段很多,不一一介绍了。

  第三个参数FontType只有3个值:

    DEVICE_FONTTYPE   1
    RASTER_FONTTYPE   2
    TRUETYPE_FONTTYPE 4  一般选这个

 

  最后一个参数LPARAM lParam其实就是EnumFontFamilies中第4个参数,可以传点用户自定义数据。

 

  下面是一个实例。

 

00450700  /.  55            push    ebp                              ;  EnumFontFamilies_Callback
00450701  |.  8BEC          mov     ebp, esp
00450703  |.  F645 10 04    test    byte ptr [ebp+10], 4    // 这里看FontType是不是TRUETYPE_FONTTYPE 
00450707  |.  8B45 08       mov     eax, dword ptr [ebp+8]  // eax = lpelf
0045070A  |.  75 07         jnz     short 00450713
0045070C  |.  B8 01000000   mov     eax, 1
00450711  |.  EB 4A         jmp     short 0045075D
00450713  |>  8A50 17       mov     dl, byte ptr [eax+17]   // [eax + 17] is lpelf->lfCharSet
00450716  |.  80FA 80       cmp     dl, 80                  // Charset -> 86 80是SJIS,改成86简体,88繁体

00450719  |.  74 07         je      short 00450722
0045071B  |.  B8 01000000   mov     eax, 1
00450720  |.  EB 3B         jmp     short 0045075D
00450722  |>  33D2          xor     edx, edx
00450724  |.  8A50 1B       mov     dl, byte ptr [eax+1B]
00450727  |.  83E2 03       and     edx, 3
0045072A  |.  4A            dec     edx
0045072B  |.  74 07         je      short 00450734
0045072D  |.  B8 01000000   mov     eax, 1
00450732  |.  EB 29         jmp     short 0045075D
00450734  |>  0FBE50 1C     movsx   edx, byte ptr [eax+1C]
00450738  |.  83FA 40       cmp     edx, 40
0045073B  |.  75 07         jnz     short 00450744
0045073D  |.  B8 01000000   mov     eax, 1
00450742  |.  EB 19         jmp     short 0045075D
00450744  |>  83C0 1C       add     eax, 1C
00450747  |.  50            push    eax                              ; /lParam
00450748  |.  6A 00         push    0                                ; |wParam = 0
0045074A  |.  68 43010000   push    143                              ; |Message = CB_ADDSTRING
0045074F  |.  8B55 14       mov     edx, dword ptr [ebp+14]          ; |
00450752  |.  52            push    edx                              ; |hWnd
00450753  |.  E8 C8741900   call    <jmp.&USER32.SendMessageA>       ; /SendMessageA
00450758  |.  B8 01000000   mov     eax, 1                           // 这里向ComboBox添加项目
0045075D  |>  5D            pop     ebp
0045075E  /.  C2 1000       retn    10

 

 

 

抱歉!评论已关闭.