Date: | September 16, 2005 / year-entry #267 |
Tags: | code |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20050916-15/?p=34163 |
Comments: | 14 |
Summary: | We concluded last time that we wanted the custom large font to apply only to the columns containing Chinese characters and leave the original font in place for the English columns. We do this by carrying two fonts around, choosing the appropriate one for each column. class RootWindow : public Window { ... private: HWND... |
We concluded last time that we wanted the custom large font to apply only to the columns containing Chinese characters and leave the original font in place for the English columns. We do this by carrying two fonts around, choosing the appropriate one for each column. class RootWindow : public Window { ... private: HWND m_hwndLV; HWND m_hwndEdit; HWND m_hwndLastFocus; HFONT m_hfChinese; HFONT m_hfNormal; int m_cyEdit; ... } RootWindow::RootWindow() : m_hfChinese(NULL) , m_hfNormal(NULL) { } RootWindow::~RootWindow() { if (m_hfChinese) DeleteObject(m_hfChinese); if (m_hfNormal) DeleteObject(m_hfNormal); } LRESULT RootWindow::OnCreate() { ... ListView_SetExtendedListViewStyleEx(m_hwndLV, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); LOGFONT lf; if (!GetObject(GetWindowFont(m_hwndLV), sizeof(lf), &lf)) { return -1; } m_hfNormal = CreateFontIndirect(&lf); if (!m_hfNormal) return -1; lf.lfHeight += lf.lfHeight / 2; // 50% bigger m_hfChinese = CreateFontIndirect(&lf); if (!m_hfChinese) return -1; SetWindowFont(m_hwndLV, m_hfChinese, FALSE); ... } Before we change the default font for the list view to the Chinese font, we create a copy of the original font (which we rather presumptuously call "normal") for safekeeping. Next, when the list view asks us to customize a column, we select the appropriate font and return the "I also changed the font" code. LRESULT RootWindow::OnLVCustomDraw(NMLVCUSTOMDRAW* pcd) { ... case CDDS_ITEMPREPAINT | CDDS_SUBITEM: pcd->clrText = m_clrTextNormal; if (pcd->iSubItem == COL_SIMP && pcd->nmcd.dwItemSpec < (DWORD)Length()) { const DictionaryEntry& de = Item(pcd->nmcd.dwItemSpec); if (de.m_pszSimp) { pcd->clrText = RGB(0x80, 0x00, 0x00); } } There are several important details here.
First, we set the Chinese font as the
"overall" font for the list view.
It would have been easier for us not to do this;
after all, since we explicitly set the font for each column,
why does it matter what the default font is?
It also would have removed the need to create a copy of the original
font.
But if you delete the
Why does the list view use the default font to decide on the line
spacing?
Because it's not clairevoyant.
That's the only font it has, after all.
It doesn't know what font you're going to select in your
Another important detail is that once we have decided to use different fonts for different columns, we are committed to selecting a font for all columns. The reason for this was discussed when we discussed how to colorize the columns.
Finally, there is the important detail of returning the
Since boldface, italics and underline are font attributes, you can use this "select a custom font" technique to make selected items display as boldface, italics, or underline, in addition to using it to change the font size as we did here. That's all for this month. Next month will be a rather boring one, adding a status bar to make the Chinese characters even more readable. After that, we'll enhance the dictionary lookup algorithm, which is itself groundwork for dynamic translation, as I may have alluded to in a previous entry. [Raymond is currently away; this message was pre-recorded.] |
Comments (14)
Comments are closed. |
Who’s Claire Voyant?
Matt: A good question indeed. According to Google, Claire Voyant is:
Victoria Lloyd ~ vocals & lyrics
Chris Ross ~ programming
Ben Fargen ~ guitars
The word in Webster’s is
http://www.m-w.com/cgi-bin/dictionary?va=clairvoyant
From just one Raymond’s post I can improve my Windows API programming skills, a learn new word and discover a new band!
In general is quite bad idea to hard-code font sizes/attributes.
Imagine someone will localize this application into Japanese. The Japanese column with have a smaller font than the Chinese one. BAD!
Same problem with other attributes (bold, italic, underscore).
Imagine italic-underscored Japanese, or Arabic.
Raymond,
Could you comment on ease of porting apps from UNIX to Windows?
regards,
Kalyan
Kalyan:
Read the "Unix to Windows Migration Guide" on MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnucmg/html/UCMGch04.asp
(I have no idea why someone in the MSDN documentation group thinks that article should be "archived" because it’s not "relevant content." Read it now before it gets even harder to find.)
My impression is that it’s not hard to port applications so long as they don’t make the mistake of thinking fork, signals, pthreads, shells, or X should ever be used. I’ve been porting math libraries from Unix to Windows for the last few years.
With mingw32, cygwin and similar tools you can easily port applications using fork. There is also a pthread<->native threads wrapper around somewhere (so pthreads are actually very portable). If the app uses GTK or Qt you are lucky on the GUI side (there is an implementation for windows) don’t know for other toolkits. For the rest you’ll have to port most function calls by hand :)
Same thing applies for TreeView – gotta set the TreeView font to be the largest font, otherwise the nodes will get clipped.
This article and several others call a function SetWindowFont(). I tried looking for where this function or method was defined in the scratch program or new scratch program or dictionary program or dialog box example, but couldn’t find it.
Now in the MSDN page at
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/propsheet/wizards.asp
one of the examples (you’ll have to unhide it to see it) also calls SetWindowFont().
Is SetWindowFont a Win32 API? Is it documented somewhere?
Norman, SetWindowFont is a macro in windowsx.h.
Tuesday, September 27, 2005 2:21 PM by Seth McCarus
> Norman, SetWindowFont is a macro in
> windowsx.h.
Thank you. I have a feeling of deja vu about that answer, and wonder if I might have asked the exact same question before. Which segues into the answer for my other question:
>> Is it documented somewhere?
Sounds like the answer’s no. Well, we know how the owner of this blog will scream and pounce on anyone who uses undocumented functions — especially when he sees someone post programs in blogs calling undocumented functions. Now waiting to see how that bloodbath will turn out ^u^
Since it’s just a bunch of macros, the file is self-documenting. If you want to see what a macro does, you can read it directly. There’s also a copy of the original documentation here http://community.borland.com/article/0,1410,17542,00.html
Wednesday, September 28, 2005 4:35 AM by oldnewthing
> Since it’s just a bunch of macros, the file
> is self-documenting.
The file self-documents what this version of the file does until the next Visual Studio service pack or (theoretically possible) Windows Update. It doesn’t document whether users are supposed to allow themselves to depend on it.
A few months ago I read that a header file in the DDK declared some functions but driver programmers weren’t supposed to call those functions. The header file self-documented itself but didn’t document that it had a mistake in itself.
More recently I’ve had a couple of disputes with your colleagues because ntddk.h and wdm.h export definitions of TCHAR and a few related identifiers (indirectly from ntdef.h but nonetheless doing it). Your colleagues say that driver programmers should know not to use these identifiers in kernel mode, but these self-documenting header files do not say so, and the writer of some code that I saw obviously had an inadequate level of clairvoyance. The MSDN pages say even less (e.g., which primitive C functions are allowed to be called in kernel mode and which aren’t, near-zero documentation). A self-documenting header file is no substitute for an MSDN page.
> There’s also a copy of the original
> documentation here
> http://community.borland.com/article/0,1410,17542,00.html
Thank you. I plan to read it a bit more fully on the weekend. Meanwhile, are other Borland documents for 3.1 also suitable for determining what identifiers we should and shouldn’t use on Windows XP? Why don’t Visual Studio and DDKs come with pointers to such relevant documents? And when we do rely on them, will you be happy to do the appcompat work to keep the results running?
In my opinion, removing the windowsx.h documentation from MSDN was a mistake.
Thursday, September 29, 2005 10:44 AM by oldnewthing
> In my opinion, removing the windowsx.h
> documentation from MSDN was a mistake.
Oh, I didn’t know it used to be there, and I wonder why you didn’t say so earlier. Now knowing that, it’s nice to reach an agreement … at least partially.
Hmm, what kind of mistake? If it was a slip of the fingers of some typist, then surely it will only take a few years for MSDN to correct the error. But if it was a deliberate exercise of poor judgement, then we should not expect a correction. If it’s the latter case, then I’m still left thinking that authors of new code aren’t supposed to use it.