1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Various utilities
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
34 #include "wx/apptrait.h"
35 #include "wx/dynload.h"
37 #include "wx/confbase.h" // for wxExpandEnvVars()
39 #include "wx/msw/private.h" // includes <windows.h>
40 #include "wx/msw/missing.h" // CHARSET_HANGUL
42 #if defined(__GNUWIN32_OLD__) || defined(__WXWINCE__) \
43 || defined(__CYGWIN32__)
44 // apparently we need to include winsock.h to get WSADATA and other stuff
45 // used in wxGetFullHostName() with the old mingw32 versions
51 #if !defined(__GNUWIN32__) && !defined(__SALFORDC__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
59 #if defined(__CYGWIN__)
60 #include <sys/unistd.h>
62 #include <sys/cygwin.h> // for cygwin_conv_to_full_win32_path()
65 #ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
66 // this (3.1 I believe) and how to test for it.
67 // If this works for Borland 4.0 as well, then no worries.
71 // VZ: there is some code using NetXXX() functions to get the full user name:
72 // I don't think it's a good idea because they don't work under Win95 and
73 // seem to return the same as wxGetUserId() under NT. If you really want
74 // to use them, just #define USE_NET_API
81 #if defined(__WIN32__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
92 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
97 // ----------------------------------------------------------------------------
99 // ----------------------------------------------------------------------------
101 // In the WIN.INI file
102 static const wxChar WX_SECTION
[] = wxT("wxWindows");
103 static const wxChar eUSERNAME
[] = wxT("UserName");
105 // ============================================================================
107 // ============================================================================
109 // ----------------------------------------------------------------------------
110 // get host name and related
111 // ----------------------------------------------------------------------------
113 // Get hostname only (without domain name)
114 bool wxGetHostName(wxChar
*buf
, int maxSize
)
116 #if defined(__WXWINCE__)
118 #elif defined(__WIN32__) && !defined(__WXMICROWIN__)
119 DWORD nSize
= maxSize
;
120 if ( !::GetComputerName(buf
, &nSize
) )
122 wxLogLastError(wxT("GetComputerName"));
130 const wxChar
*default_host
= wxT("noname");
132 if ((sysname
= wxGetenv(wxT("SYSTEM_NAME"))) == NULL
) {
133 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
135 wxStrncpy(buf
, sysname
, maxSize
- 1);
136 buf
[maxSize
] = wxT('\0');
137 return *buf
? true : false;
141 // get full hostname (with domain name if possible)
142 bool wxGetFullHostName(wxChar
*buf
, int maxSize
)
144 #if !defined( __WXMICROWIN__) && wxUSE_DYNAMIC_LOADER
145 // TODO should use GetComputerNameEx() when available
147 // we don't want to always link with Winsock DLL as we might not use it at
148 // all, so load it dynamically here if needed (and don't complain if it is
149 // missing, we handle this)
152 wxDynamicLibrary
dllWinsock(_T("ws2_32.dll"), wxDL_VERBATIM
);
153 if ( dllWinsock
.IsLoaded() )
155 typedef int (PASCAL
*WSAStartup_t
)(WORD
, WSADATA
*);
156 typedef int (PASCAL
*gethostname_t
)(char *, int);
157 typedef hostent
* (PASCAL
*gethostbyname_t
)(const char *);
158 typedef hostent
* (PASCAL
*gethostbyaddr_t
)(const char *, int , int);
159 typedef int (PASCAL
*WSACleanup_t
)(void);
161 #define LOAD_WINSOCK_FUNC(func) \
163 pfn ## func = (func ## _t)dllWinsock.GetSymbol(_T(#func))
165 LOAD_WINSOCK_FUNC(WSAStartup
);
168 if ( pfnWSAStartup
&& pfnWSAStartup(MAKEWORD(1, 1), &wsa
) == 0 )
170 LOAD_WINSOCK_FUNC(gethostname
);
173 if ( pfngethostname
)
176 if ( pfngethostname(bufA
, WXSIZEOF(bufA
)) == 0 )
178 // gethostname() won't usually include the DNS domain name,
179 // for this we need to work a bit more
180 if ( !strchr(bufA
, '.') )
182 LOAD_WINSOCK_FUNC(gethostbyname
);
184 struct hostent
*pHostEnt
= pfngethostbyname
185 ? pfngethostbyname(bufA
)
190 // Windows will use DNS internally now
191 LOAD_WINSOCK_FUNC(gethostbyaddr
);
193 pHostEnt
= pfngethostbyaddr
194 ? pfngethostbyaddr(pHostEnt
->h_addr
,
201 host
= wxString::FromAscii(pHostEnt
->h_name
);
207 LOAD_WINSOCK_FUNC(WSACleanup
);
214 wxStrncpy(buf
, host
, maxSize
);
220 #endif // !__WXMICROWIN__
222 return wxGetHostName(buf
, maxSize
);
225 // Get user ID e.g. jacs
226 bool wxGetUserId(wxChar
*buf
, int maxSize
)
228 #if defined(__WXWINCE__)
230 #elif defined(__WIN32__) && !defined(__WXMICROWIN__)
231 DWORD nSize
= maxSize
;
232 if ( ::GetUserName(buf
, &nSize
) == 0 )
234 // actually, it does happen on Win9x if the user didn't log on
235 DWORD res
= ::GetEnvironmentVariable(wxT("username"), buf
, maxSize
);
244 #else // __WXMICROWIN__
246 const wxChar
*default_id
= wxT("anonymous");
248 // Can't assume we have NIS (PC-NFS) or some other ID daemon
250 if ( (user
= wxGetenv(wxT("USER"))) == NULL
&&
251 (user
= wxGetenv(wxT("LOGNAME"))) == NULL
)
253 // Use wxWidgets configuration data (comming soon)
254 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
258 wxStrncpy(buf
, user
, maxSize
- 1);
261 return *buf
? true : false;
265 // Get user name e.g. Julian Smart
266 bool wxGetUserName(wxChar
*buf
, int maxSize
)
268 #if defined(__WXWINCE__)
270 #elif defined(USE_NET_API)
271 CHAR szUserName
[256];
272 if ( !wxGetUserId(szUserName
, WXSIZEOF(szUserName
)) )
275 // TODO how to get the domain name?
278 // the code is based on the MSDN example (also see KB article Q119670)
279 WCHAR wszUserName
[256]; // Unicode user name
280 WCHAR wszDomain
[256];
283 USER_INFO_2
*ui2
; // User structure
285 // Convert ANSI user name and domain to Unicode
286 MultiByteToWideChar( CP_ACP
, 0, szUserName
, strlen(szUserName
)+1,
287 wszUserName
, WXSIZEOF(wszUserName
) );
288 MultiByteToWideChar( CP_ACP
, 0, szDomain
, strlen(szDomain
)+1,
289 wszDomain
, WXSIZEOF(wszDomain
) );
291 // Get the computer name of a DC for the domain.
292 if ( NetGetDCName( NULL
, wszDomain
, &ComputerName
) != NERR_Success
)
294 wxLogError(wxT("Can not find domain controller"));
299 // Look up the user on the DC
300 NET_API_STATUS status
= NetUserGetInfo( (LPWSTR
)ComputerName
,
301 (LPWSTR
)&wszUserName
,
302 2, // level - we want USER_INFO_2
310 case NERR_InvalidComputer
:
311 wxLogError(wxT("Invalid domain controller name."));
315 case NERR_UserNotFound
:
316 wxLogError(wxT("Invalid user name '%s'."), szUserName
);
321 wxLogSysError(wxT("Can't get information about user"));
326 // Convert the Unicode full name to ANSI
327 WideCharToMultiByte( CP_ACP
, 0, ui2
->usri2_full_name
, -1,
328 buf
, maxSize
, NULL
, NULL
);
333 wxLogError(wxT("Couldn't look up full user name."));
336 #else // !USE_NET_API
337 // Could use NIS, MS-Mail or other site specific programs
338 // Use wxWidgets configuration data
339 bool ok
= GetProfileString(WX_SECTION
, eUSERNAME
, wxEmptyString
, buf
, maxSize
- 1) != 0;
342 ok
= wxGetUserId(buf
, maxSize
);
347 wxStrncpy(buf
, wxT("Unknown User"), maxSize
);
354 const wxChar
* wxGetHomeDir(wxString
*pstr
)
356 wxString
& strDir
= *pstr
;
358 // first branch is for Cygwin
359 #if defined(__UNIX__)
360 const wxChar
*szHome
= wxGetenv("HOME");
361 if ( szHome
== NULL
) {
363 wxLogWarning(_("can't find user's HOME, using current directory."));
369 // add a trailing slash if needed
370 if ( strDir
.Last() != wxT('/') )
374 // Cygwin returns unix type path but that does not work well
375 static wxChar windowsPath
[MAX_PATH
];
376 cygwin_conv_to_full_win32_path(strDir
, windowsPath
);
377 strDir
= windowsPath
;
379 #elif defined(__WXWINCE__)
384 // If we have a valid HOME directory, as is used on many machines that
385 // have unix utilities on them, we should use that.
386 const wxChar
*szHome
= wxGetenv(wxT("HOME"));
388 if ( szHome
!= NULL
)
392 else // no HOME, try HOMEDRIVE/PATH
394 szHome
= wxGetenv(wxT("HOMEDRIVE"));
395 if ( szHome
!= NULL
)
397 szHome
= wxGetenv(wxT("HOMEPATH"));
399 if ( szHome
!= NULL
)
403 // the idea is that under NT these variables have default values
404 // of "%systemdrive%:" and "\\". As we don't want to create our
405 // config files in the root directory of the system drive, we will
406 // create it in our program's dir. However, if the user took care
407 // to set HOMEPATH to something other than "\\", we suppose that he
408 // knows what he is doing and use the supplied value.
409 if ( wxStrcmp(szHome
, wxT("\\")) == 0 )
414 if ( strDir
.empty() )
416 // If we have a valid USERPROFILE directory, as is the case in
417 // Windows NT, 2000 and XP, we should use that as our home directory.
418 szHome
= wxGetenv(wxT("USERPROFILE"));
420 if ( szHome
!= NULL
)
424 if ( !strDir
.empty() )
426 // sometimes the value of HOME may be "%USERPROFILE%", so reexpand the
427 // value once again, it shouldn't hurt anyhow
428 strDir
= wxExpandEnvVars(strDir
);
430 else // fall back to the program directory
432 // extract the directory component of the program file name
433 wxSplitPath(wxGetFullModuleName(), &strDir
, NULL
, NULL
);
437 return strDir
.c_str();
440 wxChar
*wxGetUserHome(const wxString
& WXUNUSED(user
))
442 // VZ: the old code here never worked for user != "" anyhow! Moreover, it
443 // returned sometimes a malloc()'d pointer, sometimes a pointer to a
444 // static buffer and sometimes I don't even know what.
445 static wxString s_home
;
447 return (wxChar
*)wxGetHomeDir(&s_home
);
450 bool wxDirExists(const wxString
& dir
)
452 #ifdef __WXMICROWIN__
453 return wxPathExist(dir
);
454 #elif defined(__WIN32__)
455 DWORD attribs
= GetFileAttributes(dir
);
456 return ((attribs
!= (DWORD
)-1) && (attribs
& FILE_ATTRIBUTE_DIRECTORY
));
457 #endif // Win32/__WXMICROWIN__
460 bool wxGetDiskSpace(const wxString
& path
, wxLongLong
*pTotal
, wxLongLong
*pFree
)
468 // old w32api don't have ULARGE_INTEGER
469 #if defined(__WIN32__) && \
470 (!defined(__GNUWIN32__) || wxCHECK_W32API_VERSION( 0, 3 ))
471 // GetDiskFreeSpaceEx() is not available under original Win95, check for
473 typedef BOOL (WINAPI
*GetDiskFreeSpaceEx_t
)(LPCTSTR
,
479 pGetDiskFreeSpaceEx
= (GetDiskFreeSpaceEx_t
)::GetProcAddress
481 ::GetModuleHandle(_T("kernel32.dll")),
483 "GetDiskFreeSpaceExW"
485 "GetDiskFreeSpaceExA"
489 if ( pGetDiskFreeSpaceEx
)
491 ULARGE_INTEGER bytesFree
, bytesTotal
;
493 // may pass the path as is, GetDiskFreeSpaceEx() is smart enough
494 if ( !pGetDiskFreeSpaceEx(path
,
499 wxLogLastError(_T("GetDiskFreeSpaceEx"));
504 // ULARGE_INTEGER is a union of a 64 bit value and a struct containing
505 // two 32 bit fields which may be or may be not named - try to make it
506 // compile in all cases
507 #if defined(__BORLANDC__) && !defined(_ANONYMOUS_STRUCT)
514 *pTotal
= wxLongLong(UL(bytesTotal
).HighPart
, UL(bytesTotal
).LowPart
);
519 *pFree
= wxLongLong(UL(bytesFree
).HighPart
, UL(bytesFree
).LowPart
);
525 // there's a problem with drives larger than 2GB, GetDiskFreeSpaceEx()
526 // should be used instead - but if it's not available, fall back on
527 // GetDiskFreeSpace() nevertheless...
529 DWORD lSectorsPerCluster
,
531 lNumberOfFreeClusters
,
532 lTotalNumberOfClusters
;
534 // FIXME: this is wrong, we should extract the root drive from path
535 // instead, but this is the job for wxFileName...
536 if ( !::GetDiskFreeSpace(path
,
539 &lNumberOfFreeClusters
,
540 &lTotalNumberOfClusters
) )
542 wxLogLastError(_T("GetDiskFreeSpace"));
547 wxLongLong lBytesPerCluster
= lSectorsPerCluster
;
548 lBytesPerCluster
*= lBytesPerSector
;
552 *pTotal
= lBytesPerCluster
;
553 *pTotal
*= lTotalNumberOfClusters
;
558 *pFree
= lBytesPerCluster
;
559 *pFree
*= lNumberOfFreeClusters
;
568 // ----------------------------------------------------------------------------
570 // ----------------------------------------------------------------------------
572 bool wxGetEnv(const wxString
& var
, wxString
*value
)
577 // first get the size of the buffer
578 DWORD dwRet
= ::GetEnvironmentVariable(var
, NULL
, 0);
581 // this means that there is no such variable
587 (void)::GetEnvironmentVariable(var
, wxStringBuffer(*value
, dwRet
),
595 bool wxSetEnv(const wxString
& var
, const wxChar
*value
)
597 // some compilers have putenv() or _putenv() or _wputenv() but it's better
598 // to always use Win32 function directly instead of dealing with them
599 #if defined(__WIN32__) && !defined(__WXWINCE__)
600 if ( !::SetEnvironmentVariable(var
, value
) )
602 wxLogLastError(_T("SetEnvironmentVariable"));
608 #else // no way to set env vars
613 // ----------------------------------------------------------------------------
614 // process management
615 // ----------------------------------------------------------------------------
617 // structure used to pass parameters from wxKill() to wxEnumFindByPidProc()
618 struct wxFindByPidParams
620 wxFindByPidParams() { hwnd
= 0; pid
= 0; }
622 // the HWND used to return the result
625 // the PID we're looking from
628 DECLARE_NO_COPY_CLASS(wxFindByPidParams
)
631 // wxKill helper: EnumWindows() callback which is used to find the first (top
632 // level) window belonging to the given process
633 BOOL CALLBACK
wxEnumFindByPidProc(HWND hwnd
, LPARAM lParam
)
636 (void)::GetWindowThreadProcessId(hwnd
, &pid
);
638 wxFindByPidParams
*params
= (wxFindByPidParams
*)lParam
;
639 if ( pid
== params
->pid
)
641 // remember the window we found
644 // return FALSE to stop the enumeration
648 // continue enumeration
652 int wxKill(long pid
, wxSignal sig
, wxKillError
*krc
)
654 // get the process handle to operate on
655 HANDLE hProcess
= ::OpenProcess(SYNCHRONIZE
|
657 PROCESS_QUERY_INFORMATION
,
658 FALSE
, // not inheritable
660 if ( hProcess
== NULL
)
664 if ( ::GetLastError() == ERROR_ACCESS_DENIED
)
666 *krc
= wxKILL_ACCESS_DENIED
;
670 *krc
= wxKILL_NO_PROCESS
;
681 // kill the process forcefully returning -1 as error code
682 if ( !::TerminateProcess(hProcess
, (UINT
)-1) )
684 wxLogSysError(_("Failed to kill process %d"), pid
);
688 // this is not supposed to happen if we could open the
698 // do nothing, we just want to test for process existence
702 // any other signal means "terminate"
704 wxFindByPidParams params
;
705 params
.pid
= (DWORD
)pid
;
707 // EnumWindows() has nice semantics: it returns 0 if it found
708 // something or if an error occured and non zero if it
709 // enumerated all the window
710 if ( !::EnumWindows(wxEnumFindByPidProc
, (LPARAM
)¶ms
) )
712 // did we find any window?
715 // tell the app to close
717 // NB: this is the harshest way, the app won't have
718 // opportunity to save any files, for example, but
719 // this is probably what we want here. If not we
720 // can also use SendMesageTimeout(WM_CLOSE)
721 if ( !::PostMessage(params
.hwnd
, WM_QUIT
, 0, 0) )
723 wxLogLastError(_T("PostMessage(WM_QUIT)"));
726 else // it was an error then
728 wxLogLastError(_T("EnumWindows"));
733 else // no windows for this PID
750 // as we wait for a short time, we can use just WaitForSingleObject()
751 // and not MsgWaitForMultipleObjects()
752 switch ( ::WaitForSingleObject(hProcess
, 500 /* msec */) )
755 // process terminated
756 if ( !::GetExitCodeProcess(hProcess
, &rc
) )
758 wxLogLastError(_T("GetExitCodeProcess"));
763 wxFAIL_MSG( _T("unexpected WaitForSingleObject() return") );
767 wxLogLastError(_T("WaitForSingleObject"));
782 // just to suppress the warnings about uninitialized variable
786 ::CloseHandle(hProcess
);
788 // the return code is the same as from Unix kill(): 0 if killed
789 // successfully or -1 on error
791 // be careful to interpret rc correctly: for wxSIGNONE we return success if
792 // the process exists, for all the other sig values -- if it doesn't
794 ((sig
== wxSIGNONE
) == (rc
== STILL_ACTIVE
)) )
808 // Execute a program in an Interactive Shell
809 bool wxShell(const wxString
& command
)
816 wxChar
*shell
= wxGetenv(wxT("COMSPEC"));
818 shell
= (wxChar
*) wxT("\\COMMAND.COM");
827 // pass the command to execute to the command processor
828 cmd
.Printf(wxT("%s /c %s"), shell
, command
.c_str());
832 return wxExecute(cmd
, wxEXEC_SYNC
) == 0;
835 // Shutdown or reboot the PC
836 bool wxShutdown(wxShutdownFlags wFlags
)
840 #elif defined(__WIN32__)
843 if ( wxGetOsVersion(NULL
, NULL
) == wxWINDOWS_NT
) // if is NT or 2K
845 // Get a token for this process.
847 bOK
= ::OpenProcessToken(GetCurrentProcess(),
848 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
852 TOKEN_PRIVILEGES tkp
;
854 // Get the LUID for the shutdown privilege.
855 ::LookupPrivilegeValue(NULL
, SE_SHUTDOWN_NAME
,
856 &tkp
.Privileges
[0].Luid
);
858 tkp
.PrivilegeCount
= 1; // one privilege to set
859 tkp
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
861 // Get the shutdown privilege for this process.
862 ::AdjustTokenPrivileges(hToken
, FALSE
, &tkp
, 0,
863 (PTOKEN_PRIVILEGES
)NULL
, 0);
865 // Cannot test the return value of AdjustTokenPrivileges.
866 bOK
= ::GetLastError() == ERROR_SUCCESS
;
872 UINT flags
= EWX_SHUTDOWN
| EWX_FORCE
;
875 case wxSHUTDOWN_POWEROFF
:
876 flags
|= EWX_POWEROFF
;
879 case wxSHUTDOWN_REBOOT
:
884 wxFAIL_MSG( _T("unknown wxShutdown() flag") );
888 bOK
= ::ExitWindowsEx(flags
, 0) != 0;
895 // ----------------------------------------------------------------------------
897 // ----------------------------------------------------------------------------
899 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
900 long wxGetFreeMemory()
902 #if defined(__WIN32__) && !defined(__BORLANDC__)
903 MEMORYSTATUS memStatus
;
904 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
905 GlobalMemoryStatus(&memStatus
);
906 return memStatus
.dwAvailPhys
;
908 return (long)GetFreeSpace(0);
912 unsigned long wxGetProcessId()
914 return ::GetCurrentProcessId();
920 ::MessageBeep((UINT
)-1); // default sound
923 wxString
wxGetOsDescription()
930 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
931 if ( ::GetVersionEx(&info
) )
933 switch ( info
.dwPlatformId
)
935 case VER_PLATFORM_WIN32s
:
936 str
= _("Win32s on Windows 3.1");
939 case VER_PLATFORM_WIN32_WINDOWS
:
940 str
.Printf(_("Windows 9%c"),
941 info
.dwMinorVersion
== 0 ? _T('5') : _T('8'));
942 if ( !wxIsEmpty(info
.szCSDVersion
) )
944 str
<< _T(" (") << info
.szCSDVersion
<< _T(')');
948 case VER_PLATFORM_WIN32_NT
:
949 str
.Printf(_T("Windows NT %lu.%lu (build %lu"),
953 if ( !wxIsEmpty(info
.szCSDVersion
) )
955 str
<< _T(", ") << info
.szCSDVersion
;
963 wxFAIL_MSG( _T("GetVersionEx() failed") ); // should never happen
969 wxToolkitInfo
& wxAppTraits::GetToolkitInfo()
971 // cache the version info, it's not going to change
973 // NB: this is MT-safe, we may use these static vars from different threads
974 // but as they always have the same value it doesn't matter
975 static int s_ver
= -1,
985 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
986 if ( ::GetVersionEx(&info
) )
988 s_major
= info
.dwMajorVersion
;
989 s_minor
= info
.dwMinorVersion
;
991 switch ( info
.dwPlatformId
)
993 case VER_PLATFORM_WIN32s
:
997 case VER_PLATFORM_WIN32_WINDOWS
:
1001 case VER_PLATFORM_WIN32_NT
:
1002 s_ver
= wxWINDOWS_NT
;
1005 case VER_PLATFORM_WIN32_CE
:
1006 s_ver
= wxWINDOWS_CE
;
1013 static wxToolkitInfo info
;
1014 info
.versionMajor
= s_major
;
1015 info
.versionMinor
= s_minor
;
1017 info
.name
= _T("wxBase");
1021 // ----------------------------------------------------------------------------
1023 // ----------------------------------------------------------------------------
1025 void wxMilliSleep(unsigned long milliseconds
)
1027 ::Sleep(milliseconds
);
1030 void wxMicroSleep(unsigned long microseconds
)
1032 wxMilliSleep(microseconds
/1000);
1035 void wxSleep(int nSecs
)
1037 wxMilliSleep(1000*nSecs
);
1040 // ----------------------------------------------------------------------------
1041 // font encoding <-> Win32 codepage conversion functions
1042 // ----------------------------------------------------------------------------
1044 extern WXDLLIMPEXP_BASE
long wxEncodingToCharset(wxFontEncoding encoding
)
1048 // although this function is supposed to return an exact match, do do
1049 // some mappings here for the most common case of "standard" encoding
1050 case wxFONTENCODING_SYSTEM
:
1051 return DEFAULT_CHARSET
;
1053 case wxFONTENCODING_ISO8859_1
:
1054 case wxFONTENCODING_ISO8859_15
:
1055 case wxFONTENCODING_CP1252
:
1056 return ANSI_CHARSET
;
1058 #if !defined(__WXMICROWIN__)
1059 // The following four fonts are multi-byte charsets
1060 case wxFONTENCODING_CP932
:
1061 return SHIFTJIS_CHARSET
;
1063 case wxFONTENCODING_CP936
:
1064 return GB2312_CHARSET
;
1066 case wxFONTENCODING_CP949
:
1067 return HANGUL_CHARSET
;
1069 case wxFONTENCODING_CP950
:
1070 return CHINESEBIG5_CHARSET
;
1072 // The rest are single byte encodings
1073 case wxFONTENCODING_CP1250
:
1074 return EASTEUROPE_CHARSET
;
1076 case wxFONTENCODING_CP1251
:
1077 return RUSSIAN_CHARSET
;
1079 case wxFONTENCODING_CP1253
:
1080 return GREEK_CHARSET
;
1082 case wxFONTENCODING_CP1254
:
1083 return TURKISH_CHARSET
;
1085 case wxFONTENCODING_CP1255
:
1086 return HEBREW_CHARSET
;
1088 case wxFONTENCODING_CP1256
:
1089 return ARABIC_CHARSET
;
1091 case wxFONTENCODING_CP1257
:
1092 return BALTIC_CHARSET
;
1094 case wxFONTENCODING_CP874
:
1095 return THAI_CHARSET
;
1096 #endif // !__WXMICROWIN__
1098 case wxFONTENCODING_CP437
:
1102 // no way to translate this encoding into a Windows charset
1107 // we have 2 versions of wxCharsetToCodepage(): the old one which directly
1108 // looks up the vlaues in the registry and the new one which is more
1109 // politically correct and has more chances to work on other Windows versions
1110 // as well but the old version is still needed for !wxUSE_FONTMAP case
1113 #include "wx/fontmap.h"
1115 extern WXDLLIMPEXP_BASE
long wxEncodingToCodepage(wxFontEncoding encoding
)
1117 // translate encoding into the Windows CHARSET
1118 long charset
= wxEncodingToCharset(encoding
);
1119 if ( charset
== -1 )
1122 // translate CHARSET to code page
1123 CHARSETINFO csetInfo
;
1124 if ( !::TranslateCharsetInfo((DWORD
*)(DWORD
)charset
,
1128 wxLogLastError(_T("TranslateCharsetInfo(TCI_SRCCHARSET)"));
1133 return csetInfo
.ciACP
;
1136 extern long wxCharsetToCodepage(const wxChar
*name
)
1138 // first get the font encoding for this charset
1142 wxFontEncoding enc
= wxFontMapper::Get()->CharsetToEncoding(name
, false);
1143 if ( enc
== wxFONTENCODING_SYSTEM
)
1146 // the use the helper function
1147 return wxEncodingToCodepage(enc
);
1150 #else // !wxUSE_FONTMAP
1152 #include "wx/msw/registry.h"
1154 // this should work if Internet Exploiter is installed
1155 extern long wxCharsetToCodepage(const wxChar
*name
)
1162 wxString
path(wxT("MIME\\Database\\Charset\\"));
1165 // follow the alias loop
1168 wxRegKey
key(wxRegKey::HKCR
, path
+ cn
);
1173 // two cases: either there's an AliasForCharset string,
1174 // or there are Codepage and InternetEncoding dwords.
1175 // The InternetEncoding gives us the actual encoding,
1176 // the Codepage just says which Windows character set to
1177 // use when displaying the data.
1178 if (key
.HasValue(wxT("InternetEncoding")) &&
1179 key
.QueryValue(wxT("InternetEncoding"), &CP
))
1182 // no encoding, see if it's an alias
1183 if (!key
.HasValue(wxT("AliasForCharset")) ||
1184 !key
.QueryValue(wxT("AliasForCharset"), cn
))
1191 #endif // wxUSE_FONTMAP/!wxUSE_FONTMAP
1194 Creates a hidden window with supplied window proc registering the class for
1195 it if necesssary (i.e. the first time only). Caller is responsible for
1196 destroying the window and unregistering the class (note that this must be
1197 done because wxWidgets may be used as a DLL and so may be loaded/unloaded
1198 multiple times into/from the same process so we cna't rely on automatic
1199 Windows class unregistration).
1201 pclassname is a pointer to a caller stored classname, which must initially be
1202 NULL. classname is the desired wndclass classname. If function succesfully
1203 registers the class, pclassname will be set to classname.
1205 extern "C" WXDLLIMPEXP_BASE HWND
1206 wxCreateHiddenWindow(LPCTSTR
*pclassname
, LPCTSTR classname
, WNDPROC wndproc
)
1208 wxCHECK_MSG( classname
&& pclassname
&& wndproc
, NULL
,
1209 _T("NULL parameter in wxCreateHiddenWindow") );
1211 // register the class fi we need to first
1212 if ( *pclassname
== NULL
)
1215 wxZeroMemory(wndclass
);
1217 wndclass
.lpfnWndProc
= wndproc
;
1218 wndclass
.hInstance
= wxGetInstance();
1219 wndclass
.lpszClassName
= classname
;
1221 if ( !::RegisterClass(&wndclass
) )
1223 wxLogLastError(wxT("RegisterClass() in wxCreateHiddenWindow"));
1228 *pclassname
= classname
;
1231 // next create the window
1232 HWND hwnd
= ::CreateWindow
1246 wxLogLastError(wxT("CreateWindow() in wxCreateHiddenWindow"));