Callback function passed to EnumFontFamiliesExW uses wrong signature #1202

Open
opened 2026-01-30 22:19:01 +00:00 by claunia · 2 comments
Owner

Originally created by @beevvy on GitHub (May 18, 2019).

Example callback function used with EnumFontFamiliesExW:

int CALLBACK FontEnumForV2Console(ENUMLOGFONT *pelf, NEWTEXTMETRIC *pntm, int nFontType, LPARAM lParam);

But FONTENUMPROC as expected by EnumFontFamiliesExW is defined as follows (SDK 10.0.18362.0):

typedef int (CALLBACK* OLDFONTENUMPROCW)(CONST LOGFONTW *, CONST TEXTMETRICW *, DWORD, LPARAM);

In practice, the differing argument types are representation-compatible anyway, so it works fine, but it does require a cast on the function pointer. It was suggested in #871 to get this sorted out.

Affected files:

>git grep FONTENUMPROC
src/propsheet/misc.cpp:    EnumFontFamiliesEx(hDC, &LogFont, (FONTENUMPROC)((ShouldAllowAllMonoTTFonts()) ? FontEnumForV2Console : FontEnum), (LPARAM)&fed, 0);
src/renderer/gdi/tool/main.cpp:    EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROC)EnumFontFamiliesExProc, 0, 0 );
src/tools/fontlist/main.cpp:    EnumFontFamiliesExW(hdc.get(), &LogFont, (FONTENUMPROC)FontEnumForV2Console, (LPARAM)hdc.get(), 0);

BTW, src/renderer/gdi/tool/main.cpp is not included in any project in the solution, preventing it to be scanned by an IDE. Is that intentional?

Originally created by @beevvy on GitHub (May 18, 2019). Example callback function used with `EnumFontFamiliesExW`: ```cpp int CALLBACK FontEnumForV2Console(ENUMLOGFONT *pelf, NEWTEXTMETRIC *pntm, int nFontType, LPARAM lParam); ``` But `FONTENUMPROC` as expected by `EnumFontFamiliesExW` is defined as follows (SDK 10.0.18362.0): ```cpp typedef int (CALLBACK* OLDFONTENUMPROCW)(CONST LOGFONTW *, CONST TEXTMETRICW *, DWORD, LPARAM); ``` In practice, the differing argument types are representation-compatible anyway, so it works fine, but it does require a cast on the function pointer. It was suggested in #871 to get this sorted out. Affected files: ```none >git grep FONTENUMPROC src/propsheet/misc.cpp: EnumFontFamiliesEx(hDC, &LogFont, (FONTENUMPROC)((ShouldAllowAllMonoTTFonts()) ? FontEnumForV2Console : FontEnum), (LPARAM)&fed, 0); src/renderer/gdi/tool/main.cpp: EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROC)EnumFontFamiliesExProc, 0, 0 ); src/tools/fontlist/main.cpp: EnumFontFamiliesExW(hdc.get(), &LogFont, (FONTENUMPROC)FontEnumForV2Console, (LPARAM)hdc.get(), 0); ``` BTW, `src/renderer/gdi/tool/main.cpp` is not included in any project in the solution, preventing it to be scanned by an IDE. Is that intentional?
claunia added the Help WantedProduct-ConhostIssue-BugArea-CodeHealth labels 2026-01-30 22:19:01 +00:00
Author
Owner

@HBelusca commented on GitHub (May 20, 2019):

The actual problem here, I think, is that the function does really want to always use a NEWTEXTMETRIC pointer for its second argument (note: the ENUMLOGFONT pointer can be converted to a LOGFONTW pointer without problem).

@HBelusca commented on GitHub (May 20, 2019): The actual problem here, I think, is that the function does really want to always use a NEWTEXTMETRIC pointer for its second argument (note: the ENUMLOGFONT pointer can be converted to a LOGFONTW pointer without problem).
Author
Owner

@beevvy commented on GitHub (May 20, 2019):

The documentation of EnumFontFamiliesExW links to a legacy doc of EnumFontFamExProc, which says:

lpntme
A pointer to a structure that contains information about the physical attributes of a font. The function uses the NEWTEXTMETRICEX structure for TrueType fonts; and the TEXTMETRIC structure for other fonts.
This can be an ENUMTEXTMETRIC structure.

I believe that the correct approach would be to use the specified function signature and just cast the second argument to NEWTEXTMETRICEX*. Just like you cast the LPTHREAD_START_ROUTINE's PVOID argument to whatever type you expect.

@beevvy commented on GitHub (May 20, 2019): The documentation of `EnumFontFamiliesExW` links to [a legacy doc of EnumFontFamExProc](https://docs.microsoft.com/en-us/previous-versions//dd162618(v=vs.85)), which says: > _lpntme_ > A pointer to a structure that contains information about the physical attributes of a font. The function uses the NEWTEXTMETRICEX structure for TrueType fonts; and the TEXTMETRIC structure for other fonts. > This can be an ENUMTEXTMETRIC structure. I believe that the correct approach would be to use the specified function signature and just cast the second argument to `NEWTEXTMETRICEX*`. Just like you cast the `LPTHREAD_START_ROUTINE`'s `PVOID` argument to whatever type you expect.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#1202