source: trunk/testapp/gui/fontlist/XFont.cpp

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

  • Property svn:eol-style set to native
File size: 20.9 KB
Line 
1// XFont.cpp Version 1.1
2//
3// Author: Philip Patrick (GetFontProperties)
4//
5// Version 1.0 - Initial release of GetFontProperties()
6//
7// Modified by: Hans Dietrich
8// hdietrich2@hotmail.com
9//
10// Version 1.1: - Removed MFC dependency from GetFontProperties()
11// - Converted CFile file I/O to memory mapped file
12// - Added Unicode support
13// - Combined with my GetFontFile() routine
14//
15///////////////////////////////////////////////////////////////////////////////
16
17// Slightly modified to build out of the original package available at
18// http://www.codeproject.com/KB/GDI/xfont.aspx
19
20#include <windows.h>
21#include <tchar.h>
22#include "XFont.h"
23
24#ifdef __GNUC__
25#define TRACE(a,...) do {} while(0)
26#else
27#define TRACE ((void)0)
28#endif
29#define _ASSERTE(a) do {} while(0)
30
31#ifdef _MSC_VER
32
33#pragma warning(disable : 4127) // conditional expression is constant
34
35#else
36
37#include <minivcrt.h>
38
39#endif
40
41///////////////////////////////////////////////////////////////////////////////
42// private routines
43static LONG GetNextNameValue(HKEY key, LPCTSTR subkey, LPTSTR szName, LPTSTR szData);
44static BOOL GetWinVer(LPTSTR lpszVersion, int nVersionSize, int *nVersion);
45
46
47///////////////////////////////////////////////////////////////////////////////
48// defines used by GetWinVer()
49#define WUNKNOWNSTR _T("unknown Windows version")
50
51#define W95STR _T("Windows 95")
52#define W95SP1STR _T("Windows 95 SP1")
53#define W95OSR2STR _T("Windows 95 OSR2")
54#define W98STR _T("Windows 98")
55#define W98SP1STR _T("Windows 98 SP1")
56#define W98SESTR _T("Windows 98 SE")
57#define WMESTR _T("Windows ME")
58
59#define WNT351STR _T("Windows NT 3.51")
60#define WNT4STR _T("Windows NT 4")
61#define W2KSTR _T("Windows 2000")
62#define WXPSTR _T("Windows XP")
63
64#define WCESTR _T("Windows CE")
65
66
67#define WUNKNOWN 0
68
69#define W9XFIRST 1
70#define W95 1
71#define W95SP1 2
72#define W95OSR2 3
73#define W98 4
74#define W98SP1 5
75#define W98SE 6
76#define WME 7
77#define W9XLAST 99
78
79#define WNTFIRST 101
80#define WNT351 101
81#define WNT4 102
82#define W2K 103
83#define WXP 104
84#define WNTLAST 199
85
86#define WCEFIRST 201
87#define WCE 201
88#define WCELAST 299
89
90
91///////////////////////////////////////////////////////////////////////////////
92//
93// structs used by GetFontProperties()
94//
95typedef struct _tagFONT_PROPERTIES_ANSI
96{
97 char csName[1024];
98 char csCopyright[1024];
99 char csTrademark[1024];
100 char csFamily[1024];
101} FONT_PROPERTIES_ANSI;
102
103typedef struct _tagTT_OFFSET_TABLE
104{
105 USHORT uMajorVersion;
106 USHORT uMinorVersion;
107 USHORT uNumOfTables;
108 USHORT uSearchRange;
109 USHORT uEntrySelector;
110 USHORT uRangeShift;
111} TT_OFFSET_TABLE;
112
113typedef struct _tagTT_TABLE_DIRECTORY
114{
115 char szTag[4]; //table name
116 ULONG uCheckSum; //Check sum
117 ULONG uOffset; //Offset from beginning of file
118 ULONG uLength; //length of the table in bytes
119} TT_TABLE_DIRECTORY;
120
121typedef struct _tagTT_NAME_TABLE_HEADER
122{
123 USHORT uFSelector; //format selector. Always 0
124 USHORT uNRCount; //Name Records count
125 USHORT uStorageOffset; //Offset for strings storage, from start of the table
126} TT_NAME_TABLE_HEADER;
127
128typedef struct _tagTT_NAME_RECORD
129{
130 USHORT uPlatformID;
131 USHORT uEncodingID;
132 USHORT uLanguageID;
133 USHORT uNameID;
134 USHORT uStringLength;
135 USHORT uStringOffset; //from start of storage area
136} TT_NAME_RECORD;
137
138#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
139#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))
140
141
142///////////////////////////////////////////////////////////////////////////////
143//
144// GetFontFile()
145//
146// Purpose: Find the name of font file from the font name
147//
148// Parameters: lpszFontName - name of font
149// lpszDisplayName - pointer to buffer where font display name
150// will be copied
151// nDisplayNameSize - size of display name buffer in TCHARs
152// lpszFontFile - pointer to buffer where font file name
153// will be copied
154// nFontFileSize - size of font file buffer in TCHARs
155//
156// Returns: BOOL - TRUE = success
157//
158// Notes: This is *not* a foolproof method for finding the name of a
159// font file. If a font has been installed in a normal manner,
160// and if it is in the Windows "Font" directory, then this method
161// will probably work. It will probably work for most screen
162// fonts and TrueType fonts. However, this method might not work
163// for fonts that are created or installed dynamically, or that
164// are specific to a particular device, or that are not installed
165// into the font directory.
166//
167extern "C"
168BOOL GetFontFile(LPCTSTR lpszFontName,
169 LPTSTR lpszDisplayName,
170 int nDisplayNameSize,
171 LPTSTR lpszFontFile,
172 int nFontFileSize)
173{
174 _ASSERTE(lpszFontName && lpszFontName[0] != 0);
175 if (!lpszFontName || lpszFontName[0] == 0)
176 return FALSE;
177
178 _ASSERTE(lpszDisplayName);
179 if (!lpszDisplayName)
180 return FALSE;
181
182 _ASSERTE(lpszFontFile);
183 if (!lpszFontFile)
184 return FALSE;
185
186 lpszDisplayName[0] = _T('\0');
187 lpszFontFile[0] = _T('\0');
188
189 TCHAR szName[2 * MAX_PATH];
190 TCHAR szData[2 * MAX_PATH];
191
192 int nVersion;
193 TCHAR szVersion[100];
194 GetWinVer(szVersion, sizeof(szVersion)/sizeof(TCHAR)-1, &nVersion);
195
196 TRACE(_T("szVersion=%s\n"), szVersion);
197
198 TCHAR szFontPath[1000];
199
200 if ((nVersion >= WNTFIRST) && (nVersion <= WNTLAST))
201 _tcscpy(szFontPath, _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"));
202 else
203 _tcscpy(szFontPath, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Fonts"));
204
205 BOOL bResult = FALSE;
206
207 while (GetNextNameValue(HKEY_LOCAL_MACHINE, szFontPath, szName, szData) == ERROR_SUCCESS)
208 {
209 if (_tcsnicmp(lpszFontName, szName, _tcslen(lpszFontName)) == 0)
210 {
211 TRACE(_T("found font\n"));
212 _tcsncpy(lpszDisplayName, szName, nDisplayNameSize-1);
213 _tcsncpy(lpszFontFile, szData, nFontFileSize-1);
214 bResult = TRUE;
215 break;
216 }
217
218 szFontPath[0] = _T('\0'); // this will get next value, same key
219 }
220
221 GetNextNameValue(HKEY_LOCAL_MACHINE, NULL, NULL, NULL); // close the registry key
222
223 return bResult;
224}
225
226
227///////////////////////////////////////////////////////////////////////////////
228//
229// GetFontProperties()
230//
231// Purpose: Get font name from font file
232//
233// Parameters: lpszFilePath - file path of font file
234// lpFontPropsX - pointer to font properties struct
235//
236// Returns: BOOL - TRUE = success
237//
238extern "C"
239BOOL GetFontProperties(LPCTSTR lpszFilePath, FONT_PROPERTIES * lpFontPropsX)
240{
241 FONT_PROPERTIES_ANSI fp;
242 FONT_PROPERTIES_ANSI * lpFontProps = &fp;
243
244 memset(lpFontProps, 0, sizeof(FONT_PROPERTIES_ANSI));
245
246 HANDLE hFile = INVALID_HANDLE_VALUE;
247 hFile = ::CreateFile(lpszFilePath,
248 GENERIC_READ,// | GENERIC_WRITE,
249 0,
250 NULL,
251 OPEN_ALWAYS,
252 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
253 NULL);
254
255 if (hFile == INVALID_HANDLE_VALUE)
256 {
257 TRACE(_T("ERROR: failed to open '%s'\n"), lpszFilePath);
258 TRACE(_T("ERROR: %s failed\n"), _T("CreateFile"));
259 return FALSE;
260 }
261
262 // get the file size
263 DWORD dwFileSize = ::GetFileSize(hFile, NULL);
264
265 if (dwFileSize == INVALID_FILE_SIZE)
266 {
267 TRACE(_T("ERROR: %s failed\n"), _T("GetFileSize"));
268 ::CloseHandle(hFile);
269 return FALSE;
270 }
271
272 TRACE(_T("dwFileSize = %d\n"), dwFileSize);
273
274 // Create a file mapping object that is the current size of the file
275 HANDLE hMappedFile = NULL;
276 hMappedFile = ::CreateFileMapping(hFile,
277 NULL,
278 PAGE_READONLY, //PAGE_READWRITE,
279 0,
280 dwFileSize,
281 NULL);
282
283 if (hMappedFile == NULL)
284 {
285 TRACE(_T("ERROR: %s failed\n"), _T("CreateFileMapping"));
286 ::CloseHandle(hFile);
287 return FALSE;
288 }
289
290 LPBYTE lpMapAddress = (LPBYTE) ::MapViewOfFile(hMappedFile, // handle to file-mapping object
291 FILE_MAP_READ,//FILE_MAP_WRITE, // access mode
292 0, // high-order DWORD of offset
293 0, // low-order DWORD of offset
294 0); // number of bytes to map
295
296 if (lpMapAddress == NULL)
297 {
298 TRACE(_T("ERROR: %s failed\n"), _T("MapViewOfFile"));
299 ::CloseHandle(hMappedFile);
300 ::CloseHandle(hFile);
301 return FALSE;
302 }
303
304 BOOL bRetVal = FALSE;
305 int index = 0;
306
307 TT_OFFSET_TABLE ttOffsetTable;
308 memcpy(&ttOffsetTable, &lpMapAddress[index], sizeof(TT_OFFSET_TABLE));
309 index += sizeof(TT_OFFSET_TABLE);
310
311 ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables);
312 ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion);
313 ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion);
314
315 //check is this is a true type font and the version is 1.0
316 if (ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0)
317 return bRetVal;
318
319 TT_TABLE_DIRECTORY tblDir;
320 memset(&tblDir, 0, sizeof(TT_TABLE_DIRECTORY));
321 BOOL bFound = FALSE;
322 char szTemp[4096];
323 memset(szTemp, 0, sizeof(szTemp));
324
325 for (int i = 0; i< ttOffsetTable.uNumOfTables; i++)
326 {
327 //f.Read(&tblDir, sizeof(TT_TABLE_DIRECTORY));
328 memcpy(&tblDir, &lpMapAddress[index], sizeof(TT_TABLE_DIRECTORY));
329 index += sizeof(TT_TABLE_DIRECTORY);
330
331 strncpy(szTemp, tblDir.szTag, 4);
332 if (stricmp(szTemp, "name") == 0)
333 {
334 bFound = TRUE;
335 tblDir.uLength = SWAPLONG(tblDir.uLength);
336 tblDir.uOffset = SWAPLONG(tblDir.uOffset);
337 break;
338 }
339 else if (szTemp[0] == 0)
340 {
341 break;
342 }
343 }
344
345 if (bFound)
346 {
347 index = tblDir.uOffset;
348
349 TT_NAME_TABLE_HEADER ttNTHeader;
350 memcpy(&ttNTHeader, &lpMapAddress[index], sizeof(TT_NAME_TABLE_HEADER));
351 index += sizeof(TT_NAME_TABLE_HEADER);
352
353 ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);
354 ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);
355 TT_NAME_RECORD ttRecord;
356 bFound = FALSE;
357
358 for (int i = 0;
359 i < ttNTHeader.uNRCount &&
360 (lpFontProps->csCopyright[0] == 0 ||
361 lpFontProps->csName[0] == 0 ||
362 lpFontProps->csTrademark[0] == 0 ||
363 lpFontProps->csFamily[0] == 0);
364 i++)
365 {
366 memcpy(&ttRecord, &lpMapAddress[index], sizeof(TT_NAME_RECORD));
367 index += sizeof(TT_NAME_RECORD);
368
369 ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
370 ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
371 ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
372
373 if (ttRecord.uNameID == 1 || ttRecord.uNameID == 0 || ttRecord.uNameID == 7)
374 {
375 int nPos = index; //f.GetPosition();
376
377 index = tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset;
378
379 memset(szTemp, 0, sizeof(szTemp));
380
381 memcpy(szTemp, &lpMapAddress[index], ttRecord.uStringLength);
382 index += ttRecord.uStringLength;
383
384 if (szTemp[0] != 0)
385 {
386 _ASSERTE(strlen(szTemp) < sizeof(lpFontProps->csName));
387
388 switch (ttRecord.uNameID)
389 {
390 case 0:
391 if (lpFontProps->csCopyright[0] == 0)
392 strncpy(lpFontProps->csCopyright, szTemp,
393 sizeof(lpFontProps->csCopyright)-1);
394 break;
395
396 case 1:
397 if (lpFontProps->csFamily[0] == 0)
398 strncpy(lpFontProps->csFamily, szTemp,
399 sizeof(lpFontProps->csFamily)-1);
400 bRetVal = TRUE;
401 break;
402
403 case 4:
404 if (lpFontProps->csName[0] == 0)
405 strncpy(lpFontProps->csName, szTemp,
406 sizeof(lpFontProps->csName)-1);
407 break;
408
409 case 7:
410 if (lpFontProps->csTrademark[0] == 0)
411 strncpy(lpFontProps->csTrademark, szTemp,
412 sizeof(lpFontProps->csTrademark)-1);
413 break;
414
415 default:
416 break;
417 }
418 }
419 index = nPos;
420 }
421 }
422 }
423
424 ::UnmapViewOfFile(lpMapAddress);
425 ::CloseHandle(hMappedFile);
426 ::CloseHandle(hFile);
427
428 if (lpFontProps->csName[0] == 0)
429 strcpy(lpFontProps->csName, lpFontProps->csFamily);
430
431 memset(lpFontPropsX, 0, sizeof(FONT_PROPERTIES));
432
433#ifdef _UNICODE
434 ::MultiByteToWideChar(CP_ACP, 0, lpFontProps->csName, -1, lpFontPropsX->csName,
435 sizeof(lpFontPropsX->csName)/sizeof(TCHAR)-1);
436 ::MultiByteToWideChar(CP_ACP, 0, lpFontProps->csCopyright, -1, lpFontPropsX->csCopyright,
437 sizeof(lpFontPropsX->csCopyright)/sizeof(TCHAR)-1);
438 ::MultiByteToWideChar(CP_ACP, 0, lpFontProps->csTrademark, -1, lpFontPropsX->csTrademark,
439 sizeof(lpFontPropsX->csTrademark)/sizeof(TCHAR)-1);
440 ::MultiByteToWideChar(CP_ACP, 0, lpFontProps->csFamily, -1, lpFontPropsX->csFamily,
441 sizeof(lpFontPropsX->csFamily)/sizeof(TCHAR)-1);
442#else
443 strcpy(lpFontPropsX->csName, lpFontProps->csName);
444 strcpy(lpFontPropsX->csCopyright, lpFontProps->csCopyright);
445 strcpy(lpFontPropsX->csTrademark, lpFontProps->csTrademark);
446 strcpy(lpFontPropsX->csFamily, lpFontProps->csFamily);
447#endif
448
449 return bRetVal;
450}
451
452
453///////////////////////////////////////////////////////////////////////////////
454//
455// GetNextNameValue()
456//
457// Purpose: Get first/next name/value pair from registry
458//
459// Parameters: key - handle to open key, or predefined key
460// pszSubkey - subkey name
461// pszName - pointer to buffer that receives the value string
462// pszData - pointer to buffer that receives the data string
463//
464// Returns: LONG - return code from registry function; ERROR_SUCCESS = success
465//
466// Notes: If pszSubkey, pszName, and pszData are all NULL, then the open
467// handle will be closed.
468//
469// The first time GetNextNameValue is called, pszSubkey should be
470// specified. On subsequent calls, pszSubkey should be NULL or
471// an empty string.
472//
473static LONG GetNextNameValue(HKEY key, LPCTSTR pszSubkey, LPTSTR pszName, LPTSTR pszData)
474{
475 static HKEY hkey = NULL; // registry handle, kept open between calls
476 static DWORD dwIndex = 0; // count of values returned
477 LONG retval;
478
479 // if all parameters are NULL then close key
480 if (pszSubkey == NULL && pszName == NULL && pszData == NULL)
481 {
482 TRACE(_T("closing key\n"));
483 if (hkey)
484 RegCloseKey(hkey);
485 hkey = NULL;
486 return ERROR_SUCCESS;
487 }
488
489 // if subkey is specified then open key (first time)
490 if (pszSubkey && pszSubkey[0] != 0)
491 {
492 retval = RegOpenKeyEx(key, pszSubkey, 0, KEY_ALL_ACCESS, &hkey);
493 if (retval != ERROR_SUCCESS)
494 {
495 TRACE(_T("ERROR: RegOpenKeyEx failed\n"));
496 return retval;
497 }
498 else
499 {
500 TRACE(_T("RegOpenKeyEx ok\n"));
501 }
502 dwIndex = 0;
503 }
504 else
505 {
506 dwIndex++;
507 }
508
509 _ASSERTE(pszName != NULL && pszData != NULL);
510
511 *pszName = 0;
512 *pszData = 0;
513
514 TCHAR szValueName[MAX_PATH];
515 DWORD dwValueNameSize = sizeof(szValueName)-1;
516 BYTE szValueData[MAX_PATH];
517 DWORD dwValueDataSize = sizeof(szValueData)-1;
518 DWORD dwType = 0;
519
520 retval = RegEnumValue(hkey, dwIndex, szValueName, &dwValueNameSize, NULL,
521 &dwType, szValueData, &dwValueDataSize);
522 if (retval == ERROR_SUCCESS)
523 {
524 TRACE(_T("szValueName=<%s> szValueData=<%s>\n"), szValueName, szValueData);
525 lstrcpy(pszName, (LPTSTR)szValueName);
526 lstrcpy(pszData, (LPTSTR)szValueData);
527 }
528 else
529 {
530 TRACE(_T("RegEnumKey failed\n"));
531 }
532
533 return retval;
534}
535
536
537// from winbase.h
538#ifndef VER_PLATFORM_WIN32s
539#define VER_PLATFORM_WIN32s 0
540#endif
541#ifndef VER_PLATFORM_WIN32_WINDOWS
542#define VER_PLATFORM_WIN32_WINDOWS 1
543#endif
544#ifndef VER_PLATFORM_WIN32_NT
545#define VER_PLATFORM_WIN32_NT 2
546#endif
547#ifndef VER_PLATFORM_WIN32_CE
548#define VER_PLATFORM_WIN32_CE 3
549#endif
550
551
552/*
553 This table has been assembled from Usenet postings, personal
554 observations, and reading other people's code. Please feel
555 free to add to it or correct it.
556
557
558 dwPlatFormID dwMajorVersion dwMinorVersion dwBuildNumber
55995 1 4 0 950
56095 SP1 1 4 0 >950 && <=1080
56195 OSR2 1 4 <10 >1080
56298 1 4 10 1998
56398 SP1 1 4 10 >1998 && <2183
56498 SE 1 4 10 >=2183
565ME 1 4 90 3000
566
567NT 3.51 2 3 51
568NT 4 2 4 0 1381
5692000 2 5 0 2195
570XP 2 5 1 2600
571
572CE 3
573
574*/
575
576///////////////////////////////////////////////////////////////////////////////
577//
578// GetWinVer()
579//
580// Purpose: Get Windows version info
581//
582// Parameters: lpszVersion - pointer to buffer that receives the version
583// string
584// nVersionSize - size of the version buffer in TCHARs
585// pnVersion - pointer to int that receives the version code
586//
587// Returns: BOOL - TRUE = success
588//
589///////////////////////////////////////////////////////////////////////////////
590// GetWinVer
591static BOOL GetWinVer(LPTSTR lpszVersion, int nVersionSize, int *pnVersion)
592{
593 _tcsncpy(lpszVersion, WUNKNOWNSTR, nVersionSize-1);
594 *pnVersion = WUNKNOWN;
595
596 const TCHAR *cp = NULL;
597
598 OSVERSIONINFO osinfo;
599 osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
600
601 if (!GetVersionEx(&osinfo))
602 return FALSE;
603
604 DWORD dwPlatformId = osinfo.dwPlatformId;
605 DWORD dwMinorVersion = osinfo.dwMinorVersion;
606 DWORD dwMajorVersion = osinfo.dwMajorVersion;
607 DWORD dwBuildNumber = osinfo.dwBuildNumber & 0xFFFF; // Win 95 needs this
608 TRACE(_T("%d: %d.%d.%d\n"), dwPlatformId, dwMajorVersion, dwMinorVersion, dwBuildNumber);
609
610 if ((dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) && (dwMajorVersion == 4))
611 {
612 if ((dwMinorVersion < 10) && (dwBuildNumber == 950))
613 {
614 cp = W95STR;
615 *pnVersion = W95;
616 }
617 else if ((dwMinorVersion < 10) &&
618 ((dwBuildNumber > 950) && (dwBuildNumber <= 1080)))
619 {
620 cp = W95SP1STR;
621 *pnVersion = W95SP1;
622 }
623 else if ((dwMinorVersion < 10) && (dwBuildNumber > 1080))
624 {
625 cp = W95OSR2STR;
626 *pnVersion = W95OSR2;
627 }
628 else if ((dwMinorVersion == 10) && (dwBuildNumber == 1998))
629 {
630 cp = W98STR;
631 *pnVersion = W98;
632 }
633 else if ((dwMinorVersion == 10) &&
634 ((dwBuildNumber > 1998) && (dwBuildNumber < 2183)))
635 {
636 cp = W98SP1STR;
637 *pnVersion = W98SP1;
638 }
639 else if ((dwMinorVersion == 10) && (dwBuildNumber >= 2183))
640 {
641 cp = W98SESTR;
642 *pnVersion = W98SE;
643 }
644 else if (dwMinorVersion == 90)
645 {
646 cp = WMESTR;
647 *pnVersion = WME;
648 }
649 }
650 else if (dwPlatformId == VER_PLATFORM_WIN32_NT)
651 {
652 if ((dwMajorVersion == 3) && (dwMinorVersion == 51))
653 {
654 cp = WNT351STR;
655 *pnVersion = WNT351;
656 }
657 else if ((dwMajorVersion == 4) && (dwMinorVersion == 0))
658 {
659 cp = WNT4STR;
660 *pnVersion = WNT4;
661 }
662 else if ((dwMajorVersion == 5) && (dwMinorVersion == 0))
663 {
664 cp = W2KSTR;
665 *pnVersion = W2K;
666 }
667 else if ((dwMajorVersion == 5) && (dwMinorVersion == 1))
668 {
669 cp = WXPSTR;
670 *pnVersion = WXP;
671 }
672 }
673 else if (dwPlatformId == VER_PLATFORM_WIN32_CE)
674 {
675 cp = WCESTR;
676 *pnVersion = WCE;
677 }
678
679 _tcsncpy(lpszVersion, cp, nVersionSize-1);
680
681 return TRUE;
682}
683
Note: See TracBrowser for help on using the repository browser.