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/msw/private.h" // includes <windows.h>
38 #include "wx/msw/missing.h" // CHARSET_HANGUL
40 #if defined(__GNUWIN32_OLD__) || defined(__WXWINCE__) \
41 || defined(__CYGWIN32__)
42 // apparently we need to include winsock.h to get WSADATA and other stuff
43 // used in wxGetFullHostName() with the old mingw32 versions
49 #if !defined(__GNUWIN32__) && !defined(__SALFORDC__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
57 #if defined(__CYGWIN__)
58 #include <sys/unistd.h>
60 #include <sys/cygwin.h> // for cygwin_conv_to_full_win32_path()
63 #ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
64 // this (3.1 I believe) and how to test for it.
65 // If this works for Borland 4.0 as well, then no worries.
69 // VZ: there is some code using NetXXX() functions to get the full user name:
70 // I don't think it's a good idea because they don't work under Win95 and
71 // seem to return the same as wxGetUserId() under NT. If you really want
72 // to use them, just #define USE_NET_API
79 #if defined(__WIN32__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
90 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
95 // ----------------------------------------------------------------------------
97 // ----------------------------------------------------------------------------
99 // In the WIN.INI file
100 static const wxChar WX_SECTION
[] = wxT("wxWindows");
101 static const wxChar eUSERNAME
[] = wxT("UserName");
103 // these are only used under Win16
104 #if !defined(__WIN32__) && !defined(__WXMICROWIN__)
105 static const wxChar eHOSTNAME
[] = wxT("HostName");
106 static const wxChar eUSERID
[] = wxT("UserId");
109 // ============================================================================
111 // ============================================================================
113 // ----------------------------------------------------------------------------
114 // get host name and related
115 // ----------------------------------------------------------------------------
117 // Get hostname only (without domain name)
118 bool wxGetHostName(wxChar
*buf
, int maxSize
)
120 #if defined(__WXWINCE__)
122 #elif defined(__WIN32__) && !defined(__WXMICROWIN__)
123 DWORD nSize
= maxSize
;
124 if ( !::GetComputerName(buf
, &nSize
) )
126 wxLogLastError(wxT("GetComputerName"));
134 const wxChar
*default_host
= wxT("noname");
136 if ((sysname
= wxGetenv(wxT("SYSTEM_NAME"))) == NULL
) {
137 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
139 wxStrncpy(buf
, sysname
, maxSize
- 1);
140 buf
[maxSize
] = wxT('\0');
141 return *buf
? TRUE
: FALSE
;
145 // get full hostname (with domain name if possible)
146 bool wxGetFullHostName(wxChar
*buf
, int maxSize
)
148 #if !defined( __WXMICROWIN__) && wxUSE_DYNAMIC_LOADER
149 // TODO should use GetComputerNameEx() when available
151 // we don't want to always link with Winsock DLL as we might not use it at
152 // all, so load it dynamically here if needed
153 wxDynamicLibrary
dllWinsock(_T("ws2_32.dll"), wxDL_VERBATIM
);
154 if ( dllWinsock
.IsLoaded() )
156 typedef int (PASCAL
*WSAStartup_t
)(WORD
, WSADATA
*);
157 typedef int (PASCAL
*gethostname_t
)(char *, int);
158 typedef hostent
* (PASCAL
*gethostbyname_t
)(const char *);
159 typedef hostent
* (PASCAL
*gethostbyaddr_t
)(const char *, int , int);
160 typedef int (PASCAL
*WSACleanup_t
)(void);
162 #define LOAD_WINSOCK_FUNC(func) \
164 pfn ## func = (func ## _t)dllWinsock.GetSymbol(_T(#func))
166 LOAD_WINSOCK_FUNC(WSAStartup
);
169 if ( pfnWSAStartup
&& pfnWSAStartup(MAKEWORD(1, 1), &wsa
) == 0 )
171 LOAD_WINSOCK_FUNC(gethostname
);
174 if ( pfngethostname
)
177 if ( pfngethostname(bufA
, WXSIZEOF(bufA
)) == 0 )
179 // gethostname() won't usually include the DNS domain name,
180 // for this we need to work a bit more
181 if ( !strchr(bufA
, '.') )
183 LOAD_WINSOCK_FUNC(gethostbyname
);
185 struct hostent
*pHostEnt
= pfngethostbyname
186 ? pfngethostbyname(bufA
)
191 // Windows will use DNS internally now
192 LOAD_WINSOCK_FUNC(gethostbyaddr
);
194 pHostEnt
= pfngethostbyaddr
195 ? pfngethostbyaddr(pHostEnt
->h_addr
,
202 host
= wxString::FromAscii(pHostEnt
->h_name
);
208 LOAD_WINSOCK_FUNC(WSACleanup
);
215 wxStrncpy(buf
, host
, maxSize
);
221 #endif // !__WXMICROWIN__
223 return wxGetHostName(buf
, maxSize
);
226 // Get user ID e.g. jacs
227 bool wxGetUserId(wxChar
*buf
, int maxSize
)
229 #if defined(__WXWINCE__)
231 #elif defined(__WIN32__) && !defined(__win32s__) && !defined(__WXMICROWIN__)
232 DWORD nSize
= maxSize
;
233 if ( ::GetUserName(buf
, &nSize
) == 0 )
235 // actually, it does happen on Win9x if the user didn't log on
236 DWORD res
= ::GetEnvironmentVariable(wxT("username"), buf
, maxSize
);
245 #else // Win16 or Win32s
247 const wxChar
*default_id
= wxT("anonymous");
249 // Can't assume we have NIS (PC-NFS) or some other ID daemon
251 if ( (user
= wxGetenv(wxT("USER"))) == NULL
&&
252 (user
= wxGetenv(wxT("LOGNAME"))) == NULL
)
254 // Use wxWindows configuration data (comming soon)
255 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
259 wxStrncpy(buf
, user
, maxSize
- 1);
262 return *buf
? TRUE
: FALSE
;
266 // Get user name e.g. Julian Smart
267 bool wxGetUserName(wxChar
*buf
, int maxSize
)
269 #if defined(__WXWINCE__)
271 #elif defined(USE_NET_API)
272 CHAR szUserName
[256];
273 if ( !wxGetUserId(szUserName
, WXSIZEOF(szUserName
)) )
276 // TODO how to get the domain name?
279 // the code is based on the MSDN example (also see KB article Q119670)
280 WCHAR wszUserName
[256]; // Unicode user name
281 WCHAR wszDomain
[256];
284 USER_INFO_2
*ui2
; // User structure
286 // Convert ANSI user name and domain to Unicode
287 MultiByteToWideChar( CP_ACP
, 0, szUserName
, strlen(szUserName
)+1,
288 wszUserName
, WXSIZEOF(wszUserName
) );
289 MultiByteToWideChar( CP_ACP
, 0, szDomain
, strlen(szDomain
)+1,
290 wszDomain
, WXSIZEOF(wszDomain
) );
292 // Get the computer name of a DC for the domain.
293 if ( NetGetDCName( NULL
, wszDomain
, &ComputerName
) != NERR_Success
)
295 wxLogError(wxT("Can not find domain controller"));
300 // Look up the user on the DC
301 NET_API_STATUS status
= NetUserGetInfo( (LPWSTR
)ComputerName
,
302 (LPWSTR
)&wszUserName
,
303 2, // level - we want USER_INFO_2
311 case NERR_InvalidComputer
:
312 wxLogError(wxT("Invalid domain controller name."));
316 case NERR_UserNotFound
:
317 wxLogError(wxT("Invalid user name '%s'."), szUserName
);
322 wxLogSysError(wxT("Can't get information about user"));
327 // Convert the Unicode full name to ANSI
328 WideCharToMultiByte( CP_ACP
, 0, ui2
->usri2_full_name
, -1,
329 buf
, maxSize
, NULL
, NULL
);
334 wxLogError(wxT("Couldn't look up full user name."));
337 #else // !USE_NET_API
338 // Could use NIS, MS-Mail or other site specific programs
339 // Use wxWindows configuration data
340 bool ok
= GetProfileString(WX_SECTION
, eUSERNAME
, wxEmptyString
, buf
, maxSize
- 1) != 0;
343 ok
= wxGetUserId(buf
, maxSize
);
348 wxStrncpy(buf
, wxT("Unknown User"), maxSize
);
355 const wxChar
* wxGetHomeDir(wxString
*pstr
)
357 wxString
& strDir
= *pstr
;
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__)
385 // If we have a valid HOME directory, as is used on many machines that
386 // have unix utilities on them, we should use that.
387 const wxChar
*szHome
= wxGetenv(wxT("HOME"));
389 if ( szHome
!= NULL
)
393 else // no HOME, try HOMEDRIVE/PATH
395 szHome
= wxGetenv(wxT("HOMEDRIVE"));
396 if ( szHome
!= NULL
)
398 szHome
= wxGetenv(wxT("HOMEPATH"));
400 if ( szHome
!= NULL
)
404 // the idea is that under NT these variables have default values
405 // of "%systemdrive%:" and "\\". As we don't want to create our
406 // config files in the root directory of the system drive, we will
407 // create it in our program's dir. However, if the user took care
408 // to set HOMEPATH to something other than "\\", we suppose that he
409 // knows what he is doing and use the supplied value.
410 if ( wxStrcmp(szHome
, wxT("\\")) == 0 )
415 if ( strDir
.empty() )
417 // If we have a valid USERPROFILE directory, as is the case in
418 // Windows NT, 2000 and XP, we should use that as our home directory.
419 szHome
= wxGetenv(wxT("USERPROFILE"));
421 if ( szHome
!= NULL
)
425 if ( !strDir
.empty() )
427 return strDir
.c_str();
429 //else: fall back to the prograrm directory
431 // Win16 has no idea about home, so use the executable directory instead
434 // 260 was taken from windef.h
440 ::GetModuleFileName(::GetModuleHandle(NULL
),
441 wxStringBuffer(strPath
, MAX_PATH
), MAX_PATH
);
443 // extract the dir name
444 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
448 return strDir
.c_str();
451 wxChar
*wxGetUserHome(const wxString
& WXUNUSED(user
))
453 // VZ: the old code here never worked for user != "" anyhow! Moreover, it
454 // returned sometimes a malloc()'d pointer, sometimes a pointer to a
455 // static buffer and sometimes I don't even know what.
456 static wxString s_home
;
458 return (wxChar
*)wxGetHomeDir(&s_home
);
461 bool wxDirExists(const wxString
& dir
)
463 #ifdef __WXMICROWIN__
464 return wxPathExist(dir
);
465 #elif defined(__WIN32__)
466 DWORD attribs
= GetFileAttributes(dir
);
467 return ((attribs
!= (DWORD
)-1) && (attribs
& FILE_ATTRIBUTE_DIRECTORY
));
470 struct ffblk fileInfo
;
472 struct find_t fileInfo
;
474 // In Borland findfirst has a different argument
475 // ordering from _dos_findfirst. But _dos_findfirst
476 // _should_ be ok in both MS and Borland... why not?
478 return (findfirst(dir
, &fileInfo
, _A_SUBDIR
) == 0 &&
479 (fileInfo
.ff_attrib
& _A_SUBDIR
) != 0);
481 return (_dos_findfirst(dir
, _A_SUBDIR
, &fileInfo
) == 0) &&
482 ((fileInfo
.attrib
& _A_SUBDIR
) != 0);
487 bool wxGetDiskSpace(const wxString
& path
, wxLongLong
*pTotal
, wxLongLong
*pFree
)
495 // old w32api don't have ULARGE_INTEGER
496 #if defined(__WIN32__) && \
497 (!defined(__GNUWIN32__) || wxCHECK_W32API_VERSION( 0, 3 ))
498 // GetDiskFreeSpaceEx() is not available under original Win95, check for
500 typedef BOOL (WINAPI
*GetDiskFreeSpaceEx_t
)(LPCTSTR
,
506 pGetDiskFreeSpaceEx
= (GetDiskFreeSpaceEx_t
)::GetProcAddress
508 ::GetModuleHandle(_T("kernel32.dll")),
510 "GetDiskFreeSpaceExW"
512 "GetDiskFreeSpaceExA"
516 if ( pGetDiskFreeSpaceEx
)
518 ULARGE_INTEGER bytesFree
, bytesTotal
;
520 // may pass the path as is, GetDiskFreeSpaceEx() is smart enough
521 if ( !pGetDiskFreeSpaceEx(path
,
526 wxLogLastError(_T("GetDiskFreeSpaceEx"));
531 // ULARGE_INTEGER is a union of a 64 bit value and a struct containing
532 // two 32 bit fields which may be or may be not named - try to make it
533 // compile in all cases
534 #if defined(__BORLANDC__) && !defined(_ANONYMOUS_STRUCT)
541 *pTotal
= wxLongLong(UL(bytesTotal
).HighPart
, UL(bytesTotal
).LowPart
);
546 *pFree
= wxLongLong(UL(bytesFree
).HighPart
, UL(bytesFree
).LowPart
);
552 // there's a problem with drives larger than 2GB, GetDiskFreeSpaceEx()
553 // should be used instead - but if it's not available, fall back on
554 // GetDiskFreeSpace() nevertheless...
556 DWORD lSectorsPerCluster
,
558 lNumberOfFreeClusters
,
559 lTotalNumberOfClusters
;
561 // FIXME: this is wrong, we should extract the root drive from path
562 // instead, but this is the job for wxFileName...
563 if ( !::GetDiskFreeSpace(path
,
566 &lNumberOfFreeClusters
,
567 &lTotalNumberOfClusters
) )
569 wxLogLastError(_T("GetDiskFreeSpace"));
574 wxLongLong lBytesPerCluster
= lSectorsPerCluster
;
575 lBytesPerCluster
*= lBytesPerSector
;
579 *pTotal
= lBytesPerCluster
;
580 *pTotal
*= lTotalNumberOfClusters
;
585 *pFree
= lBytesPerCluster
;
586 *pFree
*= lNumberOfFreeClusters
;
595 // ----------------------------------------------------------------------------
597 // ----------------------------------------------------------------------------
599 bool wxGetEnv(const wxString
& var
, wxString
*value
)
603 #elif defined(__WIN16__)
604 const wxChar
* ret
= wxGetenv(var
);
615 // first get the size of the buffer
616 DWORD dwRet
= ::GetEnvironmentVariable(var
, NULL
, 0);
619 // this means that there is no such variable
625 (void)::GetEnvironmentVariable(var
, wxStringBuffer(*value
, dwRet
),
633 bool wxSetEnv(const wxString
& var
, const wxChar
*value
)
635 // some compilers have putenv() or _putenv() or _wputenv() but it's better
636 // to always use Win32 function directly instead of dealing with them
637 #if defined(__WIN32__) && !defined(__WXWINCE__)
638 if ( !::SetEnvironmentVariable(var
, value
) )
640 wxLogLastError(_T("SetEnvironmentVariable"));
646 #else // no way to set env vars
651 // ----------------------------------------------------------------------------
652 // process management
653 // ----------------------------------------------------------------------------
655 // structure used to pass parameters from wxKill() to wxEnumFindByPidProc()
656 struct wxFindByPidParams
658 wxFindByPidParams() { hwnd
= 0; pid
= 0; }
660 // the HWND used to return the result
663 // the PID we're looking from
666 DECLARE_NO_COPY_CLASS(wxFindByPidParams
)
669 // wxKill helper: EnumWindows() callback which is used to find the first (top
670 // level) window belonging to the given process
671 BOOL CALLBACK
wxEnumFindByPidProc(HWND hwnd
, LPARAM lParam
)
674 (void)::GetWindowThreadProcessId(hwnd
, &pid
);
676 wxFindByPidParams
*params
= (wxFindByPidParams
*)lParam
;
677 if ( pid
== params
->pid
)
679 // remember the window we found
682 // return FALSE to stop the enumeration
686 // continue enumeration
690 int wxKill(long pid
, wxSignal sig
, wxKillError
*krc
)
692 // get the process handle to operate on
693 HANDLE hProcess
= ::OpenProcess(SYNCHRONIZE
|
695 PROCESS_QUERY_INFORMATION
,
696 FALSE
, // not inheritable
698 if ( hProcess
== NULL
)
702 if ( ::GetLastError() == ERROR_ACCESS_DENIED
)
704 *krc
= wxKILL_ACCESS_DENIED
;
708 *krc
= wxKILL_NO_PROCESS
;
719 // kill the process forcefully returning -1 as error code
720 if ( !::TerminateProcess(hProcess
, (UINT
)-1) )
722 wxLogSysError(_("Failed to kill process %d"), pid
);
726 // this is not supposed to happen if we could open the
736 // do nothing, we just want to test for process existence
740 // any other signal means "terminate"
742 wxFindByPidParams params
;
743 params
.pid
= (DWORD
)pid
;
745 // EnumWindows() has nice semantics: it returns 0 if it found
746 // something or if an error occured and non zero if it
747 // enumerated all the window
748 if ( !::EnumWindows(wxEnumFindByPidProc
, (LPARAM
)¶ms
) )
750 // did we find any window?
753 // tell the app to close
755 // NB: this is the harshest way, the app won't have
756 // opportunity to save any files, for example, but
757 // this is probably what we want here. If not we
758 // can also use SendMesageTimeout(WM_CLOSE)
759 if ( !::PostMessage(params
.hwnd
, WM_QUIT
, 0, 0) )
761 wxLogLastError(_T("PostMessage(WM_QUIT)"));
764 else // it was an error then
766 wxLogLastError(_T("EnumWindows"));
771 else // no windows for this PID
788 // as we wait for a short time, we can use just WaitForSingleObject()
789 // and not MsgWaitForMultipleObjects()
790 switch ( ::WaitForSingleObject(hProcess
, 500 /* msec */) )
793 // process terminated
794 if ( !::GetExitCodeProcess(hProcess
, &rc
) )
796 wxLogLastError(_T("GetExitCodeProcess"));
801 wxFAIL_MSG( _T("unexpected WaitForSingleObject() return") );
805 wxLogLastError(_T("WaitForSingleObject"));
820 // just to suppress the warnings about uninitialized variable
824 ::CloseHandle(hProcess
);
826 // the return code is the same as from Unix kill(): 0 if killed
827 // successfully or -1 on error
829 // be careful to interpret rc correctly: for wxSIGNONE we return success if
830 // the process exists, for all the other sig values -- if it doesn't
832 ((sig
== wxSIGNONE
) == (rc
== STILL_ACTIVE
)) )
846 // Execute a program in an Interactive Shell
847 bool wxShell(const wxString
& command
)
852 wxChar
*shell
= wxGetenv(wxT("COMSPEC"));
854 shell
= (wxChar
*) wxT("\\COMMAND.COM");
864 // pass the command to execute to the command processor
865 cmd
.Printf(wxT("%s /c %s"), shell
, command
.c_str());
868 return wxExecute(cmd
, wxEXEC_SYNC
) == 0;
872 // Shutdown or reboot the PC
873 bool wxShutdown(wxShutdownFlags wFlags
)
877 #elif defined(__WIN32__)
880 if ( wxGetOsVersion(NULL
, NULL
) == wxWINDOWS_NT
) // if is NT or 2K
882 // Get a token for this process.
884 bOK
= ::OpenProcessToken(GetCurrentProcess(),
885 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
889 TOKEN_PRIVILEGES tkp
;
891 // Get the LUID for the shutdown privilege.
892 ::LookupPrivilegeValue(NULL
, SE_SHUTDOWN_NAME
,
893 &tkp
.Privileges
[0].Luid
);
895 tkp
.PrivilegeCount
= 1; // one privilege to set
896 tkp
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
898 // Get the shutdown privilege for this process.
899 ::AdjustTokenPrivileges(hToken
, FALSE
, &tkp
, 0,
900 (PTOKEN_PRIVILEGES
)NULL
, 0);
902 // Cannot test the return value of AdjustTokenPrivileges.
903 bOK
= ::GetLastError() == ERROR_SUCCESS
;
909 UINT flags
= EWX_SHUTDOWN
| EWX_FORCE
;
912 case wxSHUTDOWN_POWEROFF
:
913 flags
|= EWX_POWEROFF
;
916 case wxSHUTDOWN_REBOOT
:
921 wxFAIL_MSG( _T("unknown wxShutdown() flag") );
925 bOK
= ::ExitWindowsEx(EWX_SHUTDOWN
| EWX_FORCE
| EWX_REBOOT
, 0) != 0;
934 // ----------------------------------------------------------------------------
936 // ----------------------------------------------------------------------------
938 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
939 long wxGetFreeMemory()
941 #if defined(__WIN32__) && !defined(__BORLANDC__)
942 MEMORYSTATUS memStatus
;
943 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
944 GlobalMemoryStatus(&memStatus
);
945 return memStatus
.dwAvailPhys
;
947 return (long)GetFreeSpace(0);
951 unsigned long wxGetProcessId()
954 return ::GetCurrentProcessId();
963 ::MessageBeep((UINT
)-1); // default sound
966 wxString
wxGetOsDescription()
974 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
975 if ( ::GetVersionEx(&info
) )
977 switch ( info
.dwPlatformId
)
979 case VER_PLATFORM_WIN32s
:
980 str
= _("Win32s on Windows 3.1");
983 case VER_PLATFORM_WIN32_WINDOWS
:
984 str
.Printf(_("Windows 9%c"),
985 info
.dwMinorVersion
== 0 ? _T('5') : _T('8'));
986 if ( !wxIsEmpty(info
.szCSDVersion
) )
988 str
<< _T(" (") << info
.szCSDVersion
<< _T(')');
992 case VER_PLATFORM_WIN32_NT
:
993 str
.Printf(_T("Windows NT %lu.%lu (build %lu"),
997 if ( !wxIsEmpty(info
.szCSDVersion
) )
999 str
<< _T(", ") << info
.szCSDVersion
;
1007 wxFAIL_MSG( _T("GetVersionEx() failed") ); // should never happen
1012 return _("Windows 3.1");
1016 wxToolkitInfo
& wxAppTraits::GetToolkitInfo()
1018 // cache the version info, it's not going to change
1020 // NB: this is MT-safe, we may use these static vars from different threads
1021 // but as they always have the same value it doesn't matter
1022 static int s_ver
= -1,
1032 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1033 if ( ::GetVersionEx(&info
) )
1035 s_major
= info
.dwMajorVersion
;
1036 s_minor
= info
.dwMinorVersion
;
1038 switch ( info
.dwPlatformId
)
1040 case VER_PLATFORM_WIN32s
:
1044 case VER_PLATFORM_WIN32_WINDOWS
:
1048 case VER_PLATFORM_WIN32_NT
:
1049 s_ver
= wxWINDOWS_NT
;
1052 case VER_PLATFORM_WIN32_CE
:
1053 s_ver
= wxWINDOWS_CE
;
1060 static wxToolkitInfo info
;
1061 info
.versionMajor
= s_major
;
1062 info
.versionMinor
= s_minor
;
1064 info
.name
= _T("wxBase");
1068 // ----------------------------------------------------------------------------
1070 // ----------------------------------------------------------------------------
1072 void wxUsleep(unsigned long milliseconds
)
1074 ::Sleep(milliseconds
);
1077 void wxSleep(int nSecs
)
1079 wxUsleep(1000*nSecs
);
1082 // ----------------------------------------------------------------------------
1083 // font encoding <-> Win32 codepage conversion functions
1084 // ----------------------------------------------------------------------------
1086 extern WXDLLIMPEXP_BASE
long wxEncodingToCharset(wxFontEncoding encoding
)
1090 // although this function is supposed to return an exact match, do do
1091 // some mappings here for the most common case of "standard" encoding
1092 case wxFONTENCODING_SYSTEM
:
1093 return DEFAULT_CHARSET
;
1095 case wxFONTENCODING_ISO8859_1
:
1096 case wxFONTENCODING_ISO8859_15
:
1097 case wxFONTENCODING_CP1252
:
1098 return ANSI_CHARSET
;
1100 #if !defined(__WXMICROWIN__)
1101 // The following four fonts are multi-byte charsets
1102 case wxFONTENCODING_CP932
:
1103 return SHIFTJIS_CHARSET
;
1105 case wxFONTENCODING_CP936
:
1106 return GB2312_CHARSET
;
1108 case wxFONTENCODING_CP949
:
1109 return HANGUL_CHARSET
;
1111 case wxFONTENCODING_CP950
:
1112 return CHINESEBIG5_CHARSET
;
1114 // The rest are single byte encodings
1115 case wxFONTENCODING_CP1250
:
1116 return EASTEUROPE_CHARSET
;
1118 case wxFONTENCODING_CP1251
:
1119 return RUSSIAN_CHARSET
;
1121 case wxFONTENCODING_CP1253
:
1122 return GREEK_CHARSET
;
1124 case wxFONTENCODING_CP1254
:
1125 return TURKISH_CHARSET
;
1127 case wxFONTENCODING_CP1255
:
1128 return HEBREW_CHARSET
;
1130 case wxFONTENCODING_CP1256
:
1131 return ARABIC_CHARSET
;
1133 case wxFONTENCODING_CP1257
:
1134 return BALTIC_CHARSET
;
1136 case wxFONTENCODING_CP874
:
1137 return THAI_CHARSET
;
1138 #endif // !__WXMICROWIN__
1140 case wxFONTENCODING_CP437
:
1144 // no way to translate this encoding into a Windows charset
1149 // we have 2 versions of wxCharsetToCodepage(): the old one which directly
1150 // looks up the vlaues in the registry and the new one which is more
1151 // politically correct and has more chances to work on other Windows versions
1152 // as well but the old version is still needed for !wxUSE_FONTMAP case
1155 #include "wx/fontmap.h"
1157 extern WXDLLIMPEXP_BASE
long wxEncodingToCodepage(wxFontEncoding encoding
)
1159 // translate encoding into the Windows CHARSET
1160 long charset
= wxEncodingToCharset(encoding
);
1161 if ( charset
== -1 )
1164 // translate CHARSET to code page
1165 CHARSETINFO csetInfo
;
1166 if ( !::TranslateCharsetInfo((DWORD
*)(DWORD
)charset
,
1170 wxLogLastError(_T("TranslateCharsetInfo(TCI_SRCCHARSET)"));
1175 return csetInfo
.ciACP
;
1178 extern long wxCharsetToCodepage(const wxChar
*name
)
1180 // first get the font encoding for this charset
1184 wxFontEncoding enc
= wxFontMapper::Get()->CharsetToEncoding(name
, FALSE
);
1185 if ( enc
== wxFONTENCODING_SYSTEM
)
1188 // the use the helper function
1189 return wxEncodingToCodepage(enc
);
1192 #else // !wxUSE_FONTMAP
1194 #include "wx/msw/registry.h"
1196 // this should work if Internet Exploiter is installed
1197 extern long wxCharsetToCodepage(const wxChar
*name
)
1204 wxString
path(wxT("MIME\\Database\\Charset\\"));
1207 // follow the alias loop
1210 wxRegKey
key(wxRegKey::HKCR
, path
+ cn
);
1215 // two cases: either there's an AliasForCharset string,
1216 // or there are Codepage and InternetEncoding dwords.
1217 // The InternetEncoding gives us the actual encoding,
1218 // the Codepage just says which Windows character set to
1219 // use when displaying the data.
1220 if (key
.HasValue(wxT("InternetEncoding")) &&
1221 key
.QueryValue(wxT("InternetEncoding"), &CP
))
1224 // no encoding, see if it's an alias
1225 if (!key
.HasValue(wxT("AliasForCharset")) ||
1226 !key
.QueryValue(wxT("AliasForCharset"), cn
))
1233 #endif // wxUSE_FONTMAP/!wxUSE_FONTMAP
1236 Creates a hidden window with supplied window proc registering the class for
1237 it if necesssary (i.e. the first time only). Caller is responsible for
1238 destroying the window and unregistering the class (note that this must be
1239 done because wxWindows may be used as a DLL and so may be loaded/unloaded
1240 multiple times into/from the same process so we cna't rely on automatic
1241 Windows class unregistration).
1243 pclassname is a pointer to a caller stored classname, which must initially be
1244 NULL. classname is the desired wndclass classname. If function succesfully
1245 registers the class, pclassname will be set to classname.
1248 wxCreateHiddenWindow(LPCTSTR
*pclassname
, LPCTSTR classname
, WNDPROC wndproc
)
1250 wxCHECK_MSG( classname
&& pclassname
&& wndproc
, NULL
,
1251 _T("NULL parameter in wxCreateHiddenWindow") );
1253 // register the class fi we need to first
1254 if ( *pclassname
== NULL
)
1257 wxZeroMemory(wndclass
);
1259 wndclass
.lpfnWndProc
= wndproc
;
1260 wndclass
.hInstance
= wxGetInstance();
1261 wndclass
.lpszClassName
= classname
;
1263 if ( !::RegisterClass(&wndclass
) )
1265 wxLogLastError(wxT("RegisterClass() in wxCreateHiddenWindow"));
1270 *pclassname
= classname
;
1273 // next create the window
1274 HWND hwnd
= ::CreateWindow
1288 wxLogLastError(wxT("CreateWindow() in wxCreateHiddenWindow"));