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 // 260 was taken from windef.h
102 // ----------------------------------------------------------------------------
104 // ----------------------------------------------------------------------------
106 // In the WIN.INI file
107 static const wxChar WX_SECTION
[] = wxT("wxWindows");
108 static const wxChar eUSERNAME
[] = wxT("UserName");
110 // ============================================================================
112 // ============================================================================
114 #if !wxUSE_UNICODE_MSLU
116 bool wxUsingUnicowsDll()
123 bool wxUsingUnicowsDll()
125 return (wxGetOsVersion() == wxWIN95
);
130 // ----------------------------------------------------------------------------
131 // get host name and related
132 // ----------------------------------------------------------------------------
134 // Get hostname only (without domain name)
135 bool wxGetHostName(wxChar
*buf
, int maxSize
)
137 #if defined(__WXWINCE__)
139 #elif defined(__WIN32__) && !defined(__WXMICROWIN__)
140 DWORD nSize
= maxSize
;
141 if ( !::GetComputerName(buf
, &nSize
) )
143 wxLogLastError(wxT("GetComputerName"));
151 const wxChar
*default_host
= wxT("noname");
153 if ((sysname
= wxGetenv(wxT("SYSTEM_NAME"))) == NULL
) {
154 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
156 wxStrncpy(buf
, sysname
, maxSize
- 1);
157 buf
[maxSize
] = wxT('\0');
158 return *buf
? true : false;
162 // get full hostname (with domain name if possible)
163 bool wxGetFullHostName(wxChar
*buf
, int maxSize
)
165 #if !defined( __WXMICROWIN__) && wxUSE_DYNAMIC_LOADER
166 // TODO should use GetComputerNameEx() when available
168 // we don't want to always link with Winsock DLL as we might not use it at
169 // all, so load it dynamically here if needed (and don't complain if it is
170 // missing, we handle this)
173 wxDynamicLibrary
dllWinsock(_T("ws2_32.dll"), wxDL_VERBATIM
);
174 if ( dllWinsock
.IsLoaded() )
176 typedef int (PASCAL
*WSAStartup_t
)(WORD
, WSADATA
*);
177 typedef int (PASCAL
*gethostname_t
)(char *, int);
178 typedef hostent
* (PASCAL
*gethostbyname_t
)(const char *);
179 typedef hostent
* (PASCAL
*gethostbyaddr_t
)(const char *, int , int);
180 typedef int (PASCAL
*WSACleanup_t
)(void);
182 #define LOAD_WINSOCK_FUNC(func) \
184 pfn ## func = (func ## _t)dllWinsock.GetSymbol(_T(#func))
186 LOAD_WINSOCK_FUNC(WSAStartup
);
189 if ( pfnWSAStartup
&& pfnWSAStartup(MAKEWORD(1, 1), &wsa
) == 0 )
191 LOAD_WINSOCK_FUNC(gethostname
);
194 if ( pfngethostname
)
197 if ( pfngethostname(bufA
, WXSIZEOF(bufA
)) == 0 )
199 // gethostname() won't usually include the DNS domain name,
200 // for this we need to work a bit more
201 if ( !strchr(bufA
, '.') )
203 LOAD_WINSOCK_FUNC(gethostbyname
);
205 struct hostent
*pHostEnt
= pfngethostbyname
206 ? pfngethostbyname(bufA
)
211 // Windows will use DNS internally now
212 LOAD_WINSOCK_FUNC(gethostbyaddr
);
214 pHostEnt
= pfngethostbyaddr
215 ? pfngethostbyaddr(pHostEnt
->h_addr
,
222 host
= wxString::FromAscii(pHostEnt
->h_name
);
228 LOAD_WINSOCK_FUNC(WSACleanup
);
235 wxStrncpy(buf
, host
, maxSize
);
241 #endif // !__WXMICROWIN__
243 return wxGetHostName(buf
, maxSize
);
246 // Get user ID e.g. jacs
247 bool wxGetUserId(wxChar
*buf
, int maxSize
)
249 #if defined(__WXWINCE__)
251 #elif defined(__WIN32__) && !defined(__WXMICROWIN__)
252 DWORD nSize
= maxSize
;
253 if ( ::GetUserName(buf
, &nSize
) == 0 )
255 // actually, it does happen on Win9x if the user didn't log on
256 DWORD res
= ::GetEnvironmentVariable(wxT("username"), buf
, maxSize
);
265 #else // __WXMICROWIN__
267 const wxChar
*default_id
= wxT("anonymous");
269 // Can't assume we have NIS (PC-NFS) or some other ID daemon
271 if ( (user
= wxGetenv(wxT("USER"))) == NULL
&&
272 (user
= wxGetenv(wxT("LOGNAME"))) == NULL
)
274 // Use wxWidgets configuration data (comming soon)
275 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
279 wxStrncpy(buf
, user
, maxSize
- 1);
282 return *buf
? true : false;
286 // Get user name e.g. Julian Smart
287 bool wxGetUserName(wxChar
*buf
, int maxSize
)
289 #if defined(__WXWINCE__)
291 #elif defined(USE_NET_API)
292 CHAR szUserName
[256];
293 if ( !wxGetUserId(szUserName
, WXSIZEOF(szUserName
)) )
296 // TODO how to get the domain name?
299 // the code is based on the MSDN example (also see KB article Q119670)
300 WCHAR wszUserName
[256]; // Unicode user name
301 WCHAR wszDomain
[256];
304 USER_INFO_2
*ui2
; // User structure
306 // Convert ANSI user name and domain to Unicode
307 MultiByteToWideChar( CP_ACP
, 0, szUserName
, strlen(szUserName
)+1,
308 wszUserName
, WXSIZEOF(wszUserName
) );
309 MultiByteToWideChar( CP_ACP
, 0, szDomain
, strlen(szDomain
)+1,
310 wszDomain
, WXSIZEOF(wszDomain
) );
312 // Get the computer name of a DC for the domain.
313 if ( NetGetDCName( NULL
, wszDomain
, &ComputerName
) != NERR_Success
)
315 wxLogError(wxT("Can not find domain controller"));
320 // Look up the user on the DC
321 NET_API_STATUS status
= NetUserGetInfo( (LPWSTR
)ComputerName
,
322 (LPWSTR
)&wszUserName
,
323 2, // level - we want USER_INFO_2
331 case NERR_InvalidComputer
:
332 wxLogError(wxT("Invalid domain controller name."));
336 case NERR_UserNotFound
:
337 wxLogError(wxT("Invalid user name '%s'."), szUserName
);
342 wxLogSysError(wxT("Can't get information about user"));
347 // Convert the Unicode full name to ANSI
348 WideCharToMultiByte( CP_ACP
, 0, ui2
->usri2_full_name
, -1,
349 buf
, maxSize
, NULL
, NULL
);
354 wxLogError(wxT("Couldn't look up full user name."));
357 #else // !USE_NET_API
358 // Could use NIS, MS-Mail or other site specific programs
359 // Use wxWidgets configuration data
360 bool ok
= GetProfileString(WX_SECTION
, eUSERNAME
, wxEmptyString
, buf
, maxSize
- 1) != 0;
363 ok
= wxGetUserId(buf
, maxSize
);
368 wxStrncpy(buf
, wxT("Unknown User"), maxSize
);
375 const wxChar
* wxGetHomeDir(wxString
*pstr
)
377 wxString
& strDir
= *pstr
;
379 // first branch is for Cygwin
380 #if defined(__UNIX__)
381 const wxChar
*szHome
= wxGetenv("HOME");
382 if ( szHome
== NULL
) {
384 wxLogWarning(_("can't find user's HOME, using current directory."));
390 // add a trailing slash if needed
391 if ( strDir
.Last() != wxT('/') )
395 // Cygwin returns unix type path but that does not work well
396 static wxChar windowsPath
[MAX_PATH
];
397 cygwin_conv_to_full_win32_path(strDir
, windowsPath
);
398 strDir
= windowsPath
;
400 #elif defined(__WXWINCE__)
405 // If we have a valid HOME directory, as is used on many machines that
406 // have unix utilities on them, we should use that.
407 const wxChar
*szHome
= wxGetenv(wxT("HOME"));
409 if ( szHome
!= NULL
)
413 else // no HOME, try HOMEDRIVE/PATH
415 szHome
= wxGetenv(wxT("HOMEDRIVE"));
416 if ( szHome
!= NULL
)
418 szHome
= wxGetenv(wxT("HOMEPATH"));
420 if ( szHome
!= NULL
)
424 // the idea is that under NT these variables have default values
425 // of "%systemdrive%:" and "\\". As we don't want to create our
426 // config files in the root directory of the system drive, we will
427 // create it in our program's dir. However, if the user took care
428 // to set HOMEPATH to something other than "\\", we suppose that he
429 // knows what he is doing and use the supplied value.
430 if ( wxStrcmp(szHome
, wxT("\\")) == 0 )
435 if ( strDir
.empty() )
437 // If we have a valid USERPROFILE directory, as is the case in
438 // Windows NT, 2000 and XP, we should use that as our home directory.
439 szHome
= wxGetenv(wxT("USERPROFILE"));
441 if ( szHome
!= NULL
)
445 if ( !strDir
.empty() )
447 // sometimes the value of HOME may be "%USERPROFILE%", so reexpand the
448 // value once again, it shouldn't hurt anyhow
449 strDir
= wxExpandEnvVars(strDir
);
451 else // fall back to the program directory
454 ::GetModuleFileName(::GetModuleHandle(NULL
),
455 wxStringBuffer(strPath
, MAX_PATH
), MAX_PATH
);
457 // extract the dir name
458 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
462 return strDir
.c_str();
465 wxChar
*wxGetUserHome(const wxString
& WXUNUSED(user
))
467 // VZ: the old code here never worked for user != "" anyhow! Moreover, it
468 // returned sometimes a malloc()'d pointer, sometimes a pointer to a
469 // static buffer and sometimes I don't even know what.
470 static wxString s_home
;
472 return (wxChar
*)wxGetHomeDir(&s_home
);
475 bool wxDirExists(const wxString
& dir
)
477 #ifdef __WXMICROWIN__
478 return wxPathExist(dir
);
479 #elif defined(__WIN32__)
480 DWORD attribs
= GetFileAttributes(dir
);
481 return ((attribs
!= (DWORD
)-1) && (attribs
& FILE_ATTRIBUTE_DIRECTORY
));
482 #endif // Win32/__WXMICROWIN__
485 bool wxGetDiskSpace(const wxString
& path
, wxLongLong
*pTotal
, wxLongLong
*pFree
)
493 // old w32api don't have ULARGE_INTEGER
494 #if defined(__WIN32__) && \
495 (!defined(__GNUWIN32__) || wxCHECK_W32API_VERSION( 0, 3 ))
496 // GetDiskFreeSpaceEx() is not available under original Win95, check for
498 typedef BOOL (WINAPI
*GetDiskFreeSpaceEx_t
)(LPCTSTR
,
504 pGetDiskFreeSpaceEx
= (GetDiskFreeSpaceEx_t
)::GetProcAddress
506 ::GetModuleHandle(_T("kernel32.dll")),
508 "GetDiskFreeSpaceExW"
510 "GetDiskFreeSpaceExA"
514 if ( pGetDiskFreeSpaceEx
)
516 ULARGE_INTEGER bytesFree
, bytesTotal
;
518 // may pass the path as is, GetDiskFreeSpaceEx() is smart enough
519 if ( !pGetDiskFreeSpaceEx(path
,
524 wxLogLastError(_T("GetDiskFreeSpaceEx"));
529 // ULARGE_INTEGER is a union of a 64 bit value and a struct containing
530 // two 32 bit fields which may be or may be not named - try to make it
531 // compile in all cases
532 #if defined(__BORLANDC__) && !defined(_ANONYMOUS_STRUCT)
539 *pTotal
= wxLongLong(UL(bytesTotal
).HighPart
, UL(bytesTotal
).LowPart
);
544 *pFree
= wxLongLong(UL(bytesFree
).HighPart
, UL(bytesFree
).LowPart
);
550 // there's a problem with drives larger than 2GB, GetDiskFreeSpaceEx()
551 // should be used instead - but if it's not available, fall back on
552 // GetDiskFreeSpace() nevertheless...
554 DWORD lSectorsPerCluster
,
556 lNumberOfFreeClusters
,
557 lTotalNumberOfClusters
;
559 // FIXME: this is wrong, we should extract the root drive from path
560 // instead, but this is the job for wxFileName...
561 if ( !::GetDiskFreeSpace(path
,
564 &lNumberOfFreeClusters
,
565 &lTotalNumberOfClusters
) )
567 wxLogLastError(_T("GetDiskFreeSpace"));
572 wxLongLong lBytesPerCluster
= lSectorsPerCluster
;
573 lBytesPerCluster
*= lBytesPerSector
;
577 *pTotal
= lBytesPerCluster
;
578 *pTotal
*= lTotalNumberOfClusters
;
583 *pFree
= lBytesPerCluster
;
584 *pFree
*= lNumberOfFreeClusters
;
593 // ----------------------------------------------------------------------------
595 // ----------------------------------------------------------------------------
597 bool wxGetEnv(const wxString
& var
, wxString
*value
)
602 // first get the size of the buffer
603 DWORD dwRet
= ::GetEnvironmentVariable(var
, NULL
, 0);
606 // this means that there is no such variable
612 (void)::GetEnvironmentVariable(var
, wxStringBuffer(*value
, dwRet
),
620 bool wxSetEnv(const wxString
& var
, const wxChar
*value
)
622 // some compilers have putenv() or _putenv() or _wputenv() but it's better
623 // to always use Win32 function directly instead of dealing with them
624 #if defined(__WIN32__) && !defined(__WXWINCE__)
625 if ( !::SetEnvironmentVariable(var
, value
) )
627 wxLogLastError(_T("SetEnvironmentVariable"));
633 #else // no way to set env vars
638 // ----------------------------------------------------------------------------
639 // process management
640 // ----------------------------------------------------------------------------
642 // structure used to pass parameters from wxKill() to wxEnumFindByPidProc()
643 struct wxFindByPidParams
645 wxFindByPidParams() { hwnd
= 0; pid
= 0; }
647 // the HWND used to return the result
650 // the PID we're looking from
653 DECLARE_NO_COPY_CLASS(wxFindByPidParams
)
656 // wxKill helper: EnumWindows() callback which is used to find the first (top
657 // level) window belonging to the given process
658 BOOL CALLBACK
wxEnumFindByPidProc(HWND hwnd
, LPARAM lParam
)
661 (void)::GetWindowThreadProcessId(hwnd
, &pid
);
663 wxFindByPidParams
*params
= (wxFindByPidParams
*)lParam
;
664 if ( pid
== params
->pid
)
666 // remember the window we found
669 // return FALSE to stop the enumeration
673 // continue enumeration
677 int wxKill(long pid
, wxSignal sig
, wxKillError
*krc
)
679 // get the process handle to operate on
680 HANDLE hProcess
= ::OpenProcess(SYNCHRONIZE
|
682 PROCESS_QUERY_INFORMATION
,
683 FALSE
, // not inheritable
685 if ( hProcess
== NULL
)
689 if ( ::GetLastError() == ERROR_ACCESS_DENIED
)
691 *krc
= wxKILL_ACCESS_DENIED
;
695 *krc
= wxKILL_NO_PROCESS
;
706 // kill the process forcefully returning -1 as error code
707 if ( !::TerminateProcess(hProcess
, (UINT
)-1) )
709 wxLogSysError(_("Failed to kill process %d"), pid
);
713 // this is not supposed to happen if we could open the
723 // do nothing, we just want to test for process existence
727 // any other signal means "terminate"
729 wxFindByPidParams params
;
730 params
.pid
= (DWORD
)pid
;
732 // EnumWindows() has nice semantics: it returns 0 if it found
733 // something or if an error occured and non zero if it
734 // enumerated all the window
735 if ( !::EnumWindows(wxEnumFindByPidProc
, (LPARAM
)¶ms
) )
737 // did we find any window?
740 // tell the app to close
742 // NB: this is the harshest way, the app won't have
743 // opportunity to save any files, for example, but
744 // this is probably what we want here. If not we
745 // can also use SendMesageTimeout(WM_CLOSE)
746 if ( !::PostMessage(params
.hwnd
, WM_QUIT
, 0, 0) )
748 wxLogLastError(_T("PostMessage(WM_QUIT)"));
751 else // it was an error then
753 wxLogLastError(_T("EnumWindows"));
758 else // no windows for this PID
775 // as we wait for a short time, we can use just WaitForSingleObject()
776 // and not MsgWaitForMultipleObjects()
777 switch ( ::WaitForSingleObject(hProcess
, 500 /* msec */) )
780 // process terminated
781 if ( !::GetExitCodeProcess(hProcess
, &rc
) )
783 wxLogLastError(_T("GetExitCodeProcess"));
788 wxFAIL_MSG( _T("unexpected WaitForSingleObject() return") );
792 wxLogLastError(_T("WaitForSingleObject"));
807 // just to suppress the warnings about uninitialized variable
811 ::CloseHandle(hProcess
);
813 // the return code is the same as from Unix kill(): 0 if killed
814 // successfully or -1 on error
816 // be careful to interpret rc correctly: for wxSIGNONE we return success if
817 // the process exists, for all the other sig values -- if it doesn't
819 ((sig
== wxSIGNONE
) == (rc
== STILL_ACTIVE
)) )
833 // Execute a program in an Interactive Shell
834 bool wxShell(const wxString
& command
)
841 wxChar
*shell
= wxGetenv(wxT("COMSPEC"));
843 shell
= (wxChar
*) wxT("\\COMMAND.COM");
852 // pass the command to execute to the command processor
853 cmd
.Printf(wxT("%s /c %s"), shell
, command
.c_str());
857 return wxExecute(cmd
, wxEXEC_SYNC
) == 0;
860 // Shutdown or reboot the PC
861 bool wxShutdown(wxShutdownFlags wFlags
)
865 #elif defined(__WIN32__)
868 if ( wxGetOsVersion(NULL
, NULL
) == wxWINDOWS_NT
) // if is NT or 2K
870 // Get a token for this process.
872 bOK
= ::OpenProcessToken(GetCurrentProcess(),
873 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
877 TOKEN_PRIVILEGES tkp
;
879 // Get the LUID for the shutdown privilege.
880 ::LookupPrivilegeValue(NULL
, SE_SHUTDOWN_NAME
,
881 &tkp
.Privileges
[0].Luid
);
883 tkp
.PrivilegeCount
= 1; // one privilege to set
884 tkp
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
886 // Get the shutdown privilege for this process.
887 ::AdjustTokenPrivileges(hToken
, FALSE
, &tkp
, 0,
888 (PTOKEN_PRIVILEGES
)NULL
, 0);
890 // Cannot test the return value of AdjustTokenPrivileges.
891 bOK
= ::GetLastError() == ERROR_SUCCESS
;
897 UINT flags
= EWX_SHUTDOWN
| EWX_FORCE
;
900 case wxSHUTDOWN_POWEROFF
:
901 flags
|= EWX_POWEROFF
;
904 case wxSHUTDOWN_REBOOT
:
909 wxFAIL_MSG( _T("unknown wxShutdown() flag") );
913 bOK
= ::ExitWindowsEx(flags
, 0) != 0;
920 // ----------------------------------------------------------------------------
922 // ----------------------------------------------------------------------------
924 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
925 long wxGetFreeMemory()
927 #if defined(__WIN32__) && !defined(__BORLANDC__)
928 MEMORYSTATUS memStatus
;
929 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
930 GlobalMemoryStatus(&memStatus
);
931 return memStatus
.dwAvailPhys
;
933 return (long)GetFreeSpace(0);
937 unsigned long wxGetProcessId()
939 return ::GetCurrentProcessId();
945 ::MessageBeep((UINT
)-1); // default sound
948 wxString
wxGetOsDescription()
955 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
956 if ( ::GetVersionEx(&info
) )
958 switch ( info
.dwPlatformId
)
960 case VER_PLATFORM_WIN32s
:
961 str
= _("Win32s on Windows 3.1");
964 case VER_PLATFORM_WIN32_WINDOWS
:
965 str
.Printf(_("Windows 9%c"),
966 info
.dwMinorVersion
== 0 ? _T('5') : _T('8'));
967 if ( !wxIsEmpty(info
.szCSDVersion
) )
969 str
<< _T(" (") << info
.szCSDVersion
<< _T(')');
973 case VER_PLATFORM_WIN32_NT
:
974 str
.Printf(_T("Windows NT %lu.%lu (build %lu"),
978 if ( !wxIsEmpty(info
.szCSDVersion
) )
980 str
<< _T(", ") << info
.szCSDVersion
;
988 wxFAIL_MSG( _T("GetVersionEx() failed") ); // should never happen
994 wxToolkitInfo
& wxAppTraits::GetToolkitInfo()
996 // cache the version info, it's not going to change
998 // NB: this is MT-safe, we may use these static vars from different threads
999 // but as they always have the same value it doesn't matter
1000 static int s_ver
= -1,
1010 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1011 if ( ::GetVersionEx(&info
) )
1013 s_major
= info
.dwMajorVersion
;
1014 s_minor
= info
.dwMinorVersion
;
1016 switch ( info
.dwPlatformId
)
1018 case VER_PLATFORM_WIN32s
:
1022 case VER_PLATFORM_WIN32_WINDOWS
:
1026 case VER_PLATFORM_WIN32_NT
:
1027 s_ver
= wxWINDOWS_NT
;
1030 case VER_PLATFORM_WIN32_CE
:
1031 s_ver
= wxWINDOWS_CE
;
1038 static wxToolkitInfo info
;
1039 info
.versionMajor
= s_major
;
1040 info
.versionMinor
= s_minor
;
1042 info
.name
= _T("wxBase");
1046 // ----------------------------------------------------------------------------
1048 // ----------------------------------------------------------------------------
1050 void wxMilliSleep(unsigned long milliseconds
)
1052 ::Sleep(milliseconds
);
1055 void wxMicroSleep(unsigned long microseconds
)
1057 wxMilliSleep(microseconds
/1000);
1060 void wxSleep(int nSecs
)
1062 wxMilliSleep(1000*nSecs
);
1065 // ----------------------------------------------------------------------------
1066 // font encoding <-> Win32 codepage conversion functions
1067 // ----------------------------------------------------------------------------
1069 extern WXDLLIMPEXP_BASE
long wxEncodingToCharset(wxFontEncoding encoding
)
1073 // although this function is supposed to return an exact match, do do
1074 // some mappings here for the most common case of "standard" encoding
1075 case wxFONTENCODING_SYSTEM
:
1076 return DEFAULT_CHARSET
;
1078 case wxFONTENCODING_ISO8859_1
:
1079 case wxFONTENCODING_ISO8859_15
:
1080 case wxFONTENCODING_CP1252
:
1081 return ANSI_CHARSET
;
1083 #if !defined(__WXMICROWIN__)
1084 // The following four fonts are multi-byte charsets
1085 case wxFONTENCODING_CP932
:
1086 return SHIFTJIS_CHARSET
;
1088 case wxFONTENCODING_CP936
:
1089 return GB2312_CHARSET
;
1091 case wxFONTENCODING_CP949
:
1092 return HANGUL_CHARSET
;
1094 case wxFONTENCODING_CP950
:
1095 return CHINESEBIG5_CHARSET
;
1097 // The rest are single byte encodings
1098 case wxFONTENCODING_CP1250
:
1099 return EASTEUROPE_CHARSET
;
1101 case wxFONTENCODING_CP1251
:
1102 return RUSSIAN_CHARSET
;
1104 case wxFONTENCODING_CP1253
:
1105 return GREEK_CHARSET
;
1107 case wxFONTENCODING_CP1254
:
1108 return TURKISH_CHARSET
;
1110 case wxFONTENCODING_CP1255
:
1111 return HEBREW_CHARSET
;
1113 case wxFONTENCODING_CP1256
:
1114 return ARABIC_CHARSET
;
1116 case wxFONTENCODING_CP1257
:
1117 return BALTIC_CHARSET
;
1119 case wxFONTENCODING_CP874
:
1120 return THAI_CHARSET
;
1121 #endif // !__WXMICROWIN__
1123 case wxFONTENCODING_CP437
:
1127 // no way to translate this encoding into a Windows charset
1132 // we have 2 versions of wxCharsetToCodepage(): the old one which directly
1133 // looks up the vlaues in the registry and the new one which is more
1134 // politically correct and has more chances to work on other Windows versions
1135 // as well but the old version is still needed for !wxUSE_FONTMAP case
1138 #include "wx/fontmap.h"
1140 extern WXDLLIMPEXP_BASE
long wxEncodingToCodepage(wxFontEncoding encoding
)
1142 // translate encoding into the Windows CHARSET
1143 long charset
= wxEncodingToCharset(encoding
);
1144 if ( charset
== -1 )
1147 // translate CHARSET to code page
1148 CHARSETINFO csetInfo
;
1149 if ( !::TranslateCharsetInfo((DWORD
*)(DWORD
)charset
,
1153 wxLogLastError(_T("TranslateCharsetInfo(TCI_SRCCHARSET)"));
1158 return csetInfo
.ciACP
;
1161 extern long wxCharsetToCodepage(const wxChar
*name
)
1163 // first get the font encoding for this charset
1167 wxFontEncoding enc
= wxFontMapper::Get()->CharsetToEncoding(name
, false);
1168 if ( enc
== wxFONTENCODING_SYSTEM
)
1171 // the use the helper function
1172 return wxEncodingToCodepage(enc
);
1175 #else // !wxUSE_FONTMAP
1177 #include "wx/msw/registry.h"
1179 // this should work if Internet Exploiter is installed
1180 extern long wxCharsetToCodepage(const wxChar
*name
)
1187 wxString
path(wxT("MIME\\Database\\Charset\\"));
1190 // follow the alias loop
1193 wxRegKey
key(wxRegKey::HKCR
, path
+ cn
);
1198 // two cases: either there's an AliasForCharset string,
1199 // or there are Codepage and InternetEncoding dwords.
1200 // The InternetEncoding gives us the actual encoding,
1201 // the Codepage just says which Windows character set to
1202 // use when displaying the data.
1203 if (key
.HasValue(wxT("InternetEncoding")) &&
1204 key
.QueryValue(wxT("InternetEncoding"), &CP
))
1207 // no encoding, see if it's an alias
1208 if (!key
.HasValue(wxT("AliasForCharset")) ||
1209 !key
.QueryValue(wxT("AliasForCharset"), cn
))
1216 #endif // wxUSE_FONTMAP/!wxUSE_FONTMAP
1219 Creates a hidden window with supplied window proc registering the class for
1220 it if necesssary (i.e. the first time only). Caller is responsible for
1221 destroying the window and unregistering the class (note that this must be
1222 done because wxWidgets may be used as a DLL and so may be loaded/unloaded
1223 multiple times into/from the same process so we cna't rely on automatic
1224 Windows class unregistration).
1226 pclassname is a pointer to a caller stored classname, which must initially be
1227 NULL. classname is the desired wndclass classname. If function succesfully
1228 registers the class, pclassname will be set to classname.
1230 extern "C" WXDLLIMPEXP_BASE HWND
1231 wxCreateHiddenWindow(LPCTSTR
*pclassname
, LPCTSTR classname
, WNDPROC wndproc
)
1233 wxCHECK_MSG( classname
&& pclassname
&& wndproc
, NULL
,
1234 _T("NULL parameter in wxCreateHiddenWindow") );
1236 // register the class fi we need to first
1237 if ( *pclassname
== NULL
)
1240 wxZeroMemory(wndclass
);
1242 wndclass
.lpfnWndProc
= wndproc
;
1243 wndclass
.hInstance
= wxGetInstance();
1244 wndclass
.lpszClassName
= classname
;
1246 if ( !::RegisterClass(&wndclass
) )
1248 wxLogLastError(wxT("RegisterClass() in wxCreateHiddenWindow"));
1253 *pclassname
= classname
;
1256 // next create the window
1257 HWND hwnd
= ::CreateWindow
1271 wxLogLastError(wxT("CreateWindow() in wxCreateHiddenWindow"));