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 // these are only used under Win16
111 #if !defined(__WIN32__) && !defined(__WXMICROWIN__)
112 static const wxChar eHOSTNAME
[] = wxT("HostName");
113 static const wxChar eUSERID
[] = wxT("UserId");
116 // ============================================================================
118 // ============================================================================
120 // ----------------------------------------------------------------------------
121 // get host name and related
122 // ----------------------------------------------------------------------------
124 // Get hostname only (without domain name)
125 bool wxGetHostName(wxChar
*buf
, int maxSize
)
127 #if defined(__WXWINCE__)
129 #elif defined(__WIN32__) && !defined(__WXMICROWIN__)
130 DWORD nSize
= maxSize
;
131 if ( !::GetComputerName(buf
, &nSize
) )
133 wxLogLastError(wxT("GetComputerName"));
141 const wxChar
*default_host
= wxT("noname");
143 if ((sysname
= wxGetenv(wxT("SYSTEM_NAME"))) == NULL
) {
144 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
146 wxStrncpy(buf
, sysname
, maxSize
- 1);
147 buf
[maxSize
] = wxT('\0');
148 return *buf
? TRUE
: FALSE
;
152 // get full hostname (with domain name if possible)
153 bool wxGetFullHostName(wxChar
*buf
, int maxSize
)
155 #if !defined( __WXMICROWIN__) && wxUSE_DYNAMIC_LOADER
156 // TODO should use GetComputerNameEx() when available
158 // we don't want to always link with Winsock DLL as we might not use it at
159 // all, so load it dynamically here if needed
160 wxDynamicLibrary
dllWinsock(_T("ws2_32.dll"), wxDL_VERBATIM
);
161 if ( dllWinsock
.IsLoaded() )
163 typedef int (PASCAL
*WSAStartup_t
)(WORD
, WSADATA
*);
164 typedef int (PASCAL
*gethostname_t
)(char *, int);
165 typedef hostent
* (PASCAL
*gethostbyname_t
)(const char *);
166 typedef hostent
* (PASCAL
*gethostbyaddr_t
)(const char *, int , int);
167 typedef int (PASCAL
*WSACleanup_t
)(void);
169 #define LOAD_WINSOCK_FUNC(func) \
171 pfn ## func = (func ## _t)dllWinsock.GetSymbol(_T(#func))
173 LOAD_WINSOCK_FUNC(WSAStartup
);
176 if ( pfnWSAStartup
&& pfnWSAStartup(MAKEWORD(1, 1), &wsa
) == 0 )
178 LOAD_WINSOCK_FUNC(gethostname
);
181 if ( pfngethostname
)
184 if ( pfngethostname(bufA
, WXSIZEOF(bufA
)) == 0 )
186 // gethostname() won't usually include the DNS domain name,
187 // for this we need to work a bit more
188 if ( !strchr(bufA
, '.') )
190 LOAD_WINSOCK_FUNC(gethostbyname
);
192 struct hostent
*pHostEnt
= pfngethostbyname
193 ? pfngethostbyname(bufA
)
198 // Windows will use DNS internally now
199 LOAD_WINSOCK_FUNC(gethostbyaddr
);
201 pHostEnt
= pfngethostbyaddr
202 ? pfngethostbyaddr(pHostEnt
->h_addr
,
209 host
= wxString::FromAscii(pHostEnt
->h_name
);
215 LOAD_WINSOCK_FUNC(WSACleanup
);
222 wxStrncpy(buf
, host
, maxSize
);
228 #endif // !__WXMICROWIN__
230 return wxGetHostName(buf
, maxSize
);
233 // Get user ID e.g. jacs
234 bool wxGetUserId(wxChar
*buf
, int maxSize
)
236 #if defined(__WXWINCE__)
238 #elif defined(__WIN32__) && !defined(__win32s__) && !defined(__WXMICROWIN__)
239 DWORD nSize
= maxSize
;
240 if ( ::GetUserName(buf
, &nSize
) == 0 )
242 // actually, it does happen on Win9x if the user didn't log on
243 DWORD res
= ::GetEnvironmentVariable(wxT("username"), buf
, maxSize
);
252 #else // Win16 or Win32s
254 const wxChar
*default_id
= wxT("anonymous");
256 // Can't assume we have NIS (PC-NFS) or some other ID daemon
258 if ( (user
= wxGetenv(wxT("USER"))) == NULL
&&
259 (user
= wxGetenv(wxT("LOGNAME"))) == NULL
)
261 // Use wxWindows configuration data (comming soon)
262 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
266 wxStrncpy(buf
, user
, maxSize
- 1);
269 return *buf
? TRUE
: FALSE
;
273 // Get user name e.g. Julian Smart
274 bool wxGetUserName(wxChar
*buf
, int maxSize
)
276 #if defined(__WXWINCE__)
278 #elif defined(USE_NET_API)
279 CHAR szUserName
[256];
280 if ( !wxGetUserId(szUserName
, WXSIZEOF(szUserName
)) )
283 // TODO how to get the domain name?
286 // the code is based on the MSDN example (also see KB article Q119670)
287 WCHAR wszUserName
[256]; // Unicode user name
288 WCHAR wszDomain
[256];
291 USER_INFO_2
*ui2
; // User structure
293 // Convert ANSI user name and domain to Unicode
294 MultiByteToWideChar( CP_ACP
, 0, szUserName
, strlen(szUserName
)+1,
295 wszUserName
, WXSIZEOF(wszUserName
) );
296 MultiByteToWideChar( CP_ACP
, 0, szDomain
, strlen(szDomain
)+1,
297 wszDomain
, WXSIZEOF(wszDomain
) );
299 // Get the computer name of a DC for the domain.
300 if ( NetGetDCName( NULL
, wszDomain
, &ComputerName
) != NERR_Success
)
302 wxLogError(wxT("Can not find domain controller"));
307 // Look up the user on the DC
308 NET_API_STATUS status
= NetUserGetInfo( (LPWSTR
)ComputerName
,
309 (LPWSTR
)&wszUserName
,
310 2, // level - we want USER_INFO_2
318 case NERR_InvalidComputer
:
319 wxLogError(wxT("Invalid domain controller name."));
323 case NERR_UserNotFound
:
324 wxLogError(wxT("Invalid user name '%s'."), szUserName
);
329 wxLogSysError(wxT("Can't get information about user"));
334 // Convert the Unicode full name to ANSI
335 WideCharToMultiByte( CP_ACP
, 0, ui2
->usri2_full_name
, -1,
336 buf
, maxSize
, NULL
, NULL
);
341 wxLogError(wxT("Couldn't look up full user name."));
344 #else // !USE_NET_API
345 // Could use NIS, MS-Mail or other site specific programs
346 // Use wxWindows configuration data
347 bool ok
= GetProfileString(WX_SECTION
, eUSERNAME
, wxEmptyString
, buf
, maxSize
- 1) != 0;
350 ok
= wxGetUserId(buf
, maxSize
);
355 wxStrncpy(buf
, wxT("Unknown User"), maxSize
);
362 const wxChar
* wxGetHomeDir(wxString
*pstr
)
364 wxString
& strDir
= *pstr
;
366 // first branch is for Cygwin
367 #if defined(__UNIX__)
368 const wxChar
*szHome
= wxGetenv("HOME");
369 if ( szHome
== NULL
) {
371 wxLogWarning(_("can't find user's HOME, using current directory."));
377 // add a trailing slash if needed
378 if ( strDir
.Last() != wxT('/') )
382 // Cygwin returns unix type path but that does not work well
383 static wxChar windowsPath
[MAX_PATH
];
384 cygwin_conv_to_full_win32_path(strDir
, windowsPath
);
385 strDir
= windowsPath
;
387 #elif defined(__WXWINCE__)
392 // If we have a valid HOME directory, as is used on many machines that
393 // have unix utilities on them, we should use that.
394 const wxChar
*szHome
= wxGetenv(wxT("HOME"));
396 if ( szHome
!= NULL
)
400 else // no HOME, try HOMEDRIVE/PATH
402 szHome
= wxGetenv(wxT("HOMEDRIVE"));
403 if ( szHome
!= NULL
)
405 szHome
= wxGetenv(wxT("HOMEPATH"));
407 if ( szHome
!= NULL
)
411 // the idea is that under NT these variables have default values
412 // of "%systemdrive%:" and "\\". As we don't want to create our
413 // config files in the root directory of the system drive, we will
414 // create it in our program's dir. However, if the user took care
415 // to set HOMEPATH to something other than "\\", we suppose that he
416 // knows what he is doing and use the supplied value.
417 if ( wxStrcmp(szHome
, wxT("\\")) == 0 )
422 if ( strDir
.empty() )
424 // If we have a valid USERPROFILE directory, as is the case in
425 // Windows NT, 2000 and XP, we should use that as our home directory.
426 szHome
= wxGetenv(wxT("USERPROFILE"));
428 if ( szHome
!= NULL
)
432 if ( !strDir
.empty() )
434 // sometimes the value of HOME may be "%USERPROFILE%", so reexpand the
435 // value once again, it shouldn't hurt anyhow
436 strDir
= wxExpandEnvVars(strDir
);
438 else // fall back to the program directory
441 ::GetModuleFileName(::GetModuleHandle(NULL
),
442 wxStringBuffer(strPath
, MAX_PATH
), MAX_PATH
);
444 // extract the dir name
445 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
449 return strDir
.c_str();
452 wxChar
*wxGetUserHome(const wxString
& WXUNUSED(user
))
454 // VZ: the old code here never worked for user != "" anyhow! Moreover, it
455 // returned sometimes a malloc()'d pointer, sometimes a pointer to a
456 // static buffer and sometimes I don't even know what.
457 static wxString s_home
;
459 return (wxChar
*)wxGetHomeDir(&s_home
);
462 bool wxDirExists(const wxString
& dir
)
464 #ifdef __WXMICROWIN__
465 return wxPathExist(dir
);
466 #elif defined(__WIN32__)
467 DWORD attribs
= GetFileAttributes(dir
);
468 return ((attribs
!= (DWORD
)-1) && (attribs
& FILE_ATTRIBUTE_DIRECTORY
));
471 struct ffblk fileInfo
;
473 struct find_t fileInfo
;
475 // In Borland findfirst has a different argument
476 // ordering from _dos_findfirst. But _dos_findfirst
477 // _should_ be ok in both MS and Borland... why not?
479 return (findfirst(dir
, &fileInfo
, _A_SUBDIR
) == 0 &&
480 (fileInfo
.ff_attrib
& _A_SUBDIR
) != 0);
482 return (_dos_findfirst(dir
, _A_SUBDIR
, &fileInfo
) == 0) &&
483 ((fileInfo
.attrib
& _A_SUBDIR
) != 0);
488 bool wxGetDiskSpace(const wxString
& path
, wxLongLong
*pTotal
, wxLongLong
*pFree
)
496 // old w32api don't have ULARGE_INTEGER
497 #if defined(__WIN32__) && \
498 (!defined(__GNUWIN32__) || wxCHECK_W32API_VERSION( 0, 3 ))
499 // GetDiskFreeSpaceEx() is not available under original Win95, check for
501 typedef BOOL (WINAPI
*GetDiskFreeSpaceEx_t
)(LPCTSTR
,
507 pGetDiskFreeSpaceEx
= (GetDiskFreeSpaceEx_t
)::GetProcAddress
509 ::GetModuleHandle(_T("kernel32.dll")),
511 "GetDiskFreeSpaceExW"
513 "GetDiskFreeSpaceExA"
517 if ( pGetDiskFreeSpaceEx
)
519 ULARGE_INTEGER bytesFree
, bytesTotal
;
521 // may pass the path as is, GetDiskFreeSpaceEx() is smart enough
522 if ( !pGetDiskFreeSpaceEx(path
,
527 wxLogLastError(_T("GetDiskFreeSpaceEx"));
532 // ULARGE_INTEGER is a union of a 64 bit value and a struct containing
533 // two 32 bit fields which may be or may be not named - try to make it
534 // compile in all cases
535 #if defined(__BORLANDC__) && !defined(_ANONYMOUS_STRUCT)
542 *pTotal
= wxLongLong(UL(bytesTotal
).HighPart
, UL(bytesTotal
).LowPart
);
547 *pFree
= wxLongLong(UL(bytesFree
).HighPart
, UL(bytesFree
).LowPart
);
553 // there's a problem with drives larger than 2GB, GetDiskFreeSpaceEx()
554 // should be used instead - but if it's not available, fall back on
555 // GetDiskFreeSpace() nevertheless...
557 DWORD lSectorsPerCluster
,
559 lNumberOfFreeClusters
,
560 lTotalNumberOfClusters
;
562 // FIXME: this is wrong, we should extract the root drive from path
563 // instead, but this is the job for wxFileName...
564 if ( !::GetDiskFreeSpace(path
,
567 &lNumberOfFreeClusters
,
568 &lTotalNumberOfClusters
) )
570 wxLogLastError(_T("GetDiskFreeSpace"));
575 wxLongLong lBytesPerCluster
= lSectorsPerCluster
;
576 lBytesPerCluster
*= lBytesPerSector
;
580 *pTotal
= lBytesPerCluster
;
581 *pTotal
*= lTotalNumberOfClusters
;
586 *pFree
= lBytesPerCluster
;
587 *pFree
*= lNumberOfFreeClusters
;
596 // ----------------------------------------------------------------------------
598 // ----------------------------------------------------------------------------
600 bool wxGetEnv(const wxString
& var
, wxString
*value
)
604 #elif defined(__WIN16__)
605 const wxChar
* ret
= wxGetenv(var
);
616 // first get the size of the buffer
617 DWORD dwRet
= ::GetEnvironmentVariable(var
, NULL
, 0);
620 // this means that there is no such variable
626 (void)::GetEnvironmentVariable(var
, wxStringBuffer(*value
, dwRet
),
634 bool wxSetEnv(const wxString
& var
, const wxChar
*value
)
636 // some compilers have putenv() or _putenv() or _wputenv() but it's better
637 // to always use Win32 function directly instead of dealing with them
638 #if defined(__WIN32__) && !defined(__WXWINCE__)
639 if ( !::SetEnvironmentVariable(var
, value
) )
641 wxLogLastError(_T("SetEnvironmentVariable"));
647 #else // no way to set env vars
652 // ----------------------------------------------------------------------------
653 // process management
654 // ----------------------------------------------------------------------------
656 // structure used to pass parameters from wxKill() to wxEnumFindByPidProc()
657 struct wxFindByPidParams
659 wxFindByPidParams() { hwnd
= 0; pid
= 0; }
661 // the HWND used to return the result
664 // the PID we're looking from
667 DECLARE_NO_COPY_CLASS(wxFindByPidParams
)
670 // wxKill helper: EnumWindows() callback which is used to find the first (top
671 // level) window belonging to the given process
672 BOOL CALLBACK
wxEnumFindByPidProc(HWND hwnd
, LPARAM lParam
)
675 (void)::GetWindowThreadProcessId(hwnd
, &pid
);
677 wxFindByPidParams
*params
= (wxFindByPidParams
*)lParam
;
678 if ( pid
== params
->pid
)
680 // remember the window we found
683 // return FALSE to stop the enumeration
687 // continue enumeration
691 int wxKill(long pid
, wxSignal sig
, wxKillError
*krc
)
693 // get the process handle to operate on
694 HANDLE hProcess
= ::OpenProcess(SYNCHRONIZE
|
696 PROCESS_QUERY_INFORMATION
,
697 FALSE
, // not inheritable
699 if ( hProcess
== NULL
)
703 if ( ::GetLastError() == ERROR_ACCESS_DENIED
)
705 *krc
= wxKILL_ACCESS_DENIED
;
709 *krc
= wxKILL_NO_PROCESS
;
720 // kill the process forcefully returning -1 as error code
721 if ( !::TerminateProcess(hProcess
, (UINT
)-1) )
723 wxLogSysError(_("Failed to kill process %d"), pid
);
727 // this is not supposed to happen if we could open the
737 // do nothing, we just want to test for process existence
741 // any other signal means "terminate"
743 wxFindByPidParams params
;
744 params
.pid
= (DWORD
)pid
;
746 // EnumWindows() has nice semantics: it returns 0 if it found
747 // something or if an error occured and non zero if it
748 // enumerated all the window
749 if ( !::EnumWindows(wxEnumFindByPidProc
, (LPARAM
)¶ms
) )
751 // did we find any window?
754 // tell the app to close
756 // NB: this is the harshest way, the app won't have
757 // opportunity to save any files, for example, but
758 // this is probably what we want here. If not we
759 // can also use SendMesageTimeout(WM_CLOSE)
760 if ( !::PostMessage(params
.hwnd
, WM_QUIT
, 0, 0) )
762 wxLogLastError(_T("PostMessage(WM_QUIT)"));
765 else // it was an error then
767 wxLogLastError(_T("EnumWindows"));
772 else // no windows for this PID
789 // as we wait for a short time, we can use just WaitForSingleObject()
790 // and not MsgWaitForMultipleObjects()
791 switch ( ::WaitForSingleObject(hProcess
, 500 /* msec */) )
794 // process terminated
795 if ( !::GetExitCodeProcess(hProcess
, &rc
) )
797 wxLogLastError(_T("GetExitCodeProcess"));
802 wxFAIL_MSG( _T("unexpected WaitForSingleObject() return") );
806 wxLogLastError(_T("WaitForSingleObject"));
821 // just to suppress the warnings about uninitialized variable
825 ::CloseHandle(hProcess
);
827 // the return code is the same as from Unix kill(): 0 if killed
828 // successfully or -1 on error
830 // be careful to interpret rc correctly: for wxSIGNONE we return success if
831 // the process exists, for all the other sig values -- if it doesn't
833 ((sig
== wxSIGNONE
) == (rc
== STILL_ACTIVE
)) )
847 // Execute a program in an Interactive Shell
848 bool wxShell(const wxString
& command
)
853 wxChar
*shell
= wxGetenv(wxT("COMSPEC"));
855 shell
= (wxChar
*) wxT("\\COMMAND.COM");
865 // pass the command to execute to the command processor
866 cmd
.Printf(wxT("%s /c %s"), shell
, command
.c_str());
869 return wxExecute(cmd
, wxEXEC_SYNC
) == 0;
873 // Shutdown or reboot the PC
874 bool wxShutdown(wxShutdownFlags wFlags
)
878 #elif defined(__WIN32__)
881 if ( wxGetOsVersion(NULL
, NULL
) == wxWINDOWS_NT
) // if is NT or 2K
883 // Get a token for this process.
885 bOK
= ::OpenProcessToken(GetCurrentProcess(),
886 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
890 TOKEN_PRIVILEGES tkp
;
892 // Get the LUID for the shutdown privilege.
893 ::LookupPrivilegeValue(NULL
, SE_SHUTDOWN_NAME
,
894 &tkp
.Privileges
[0].Luid
);
896 tkp
.PrivilegeCount
= 1; // one privilege to set
897 tkp
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
899 // Get the shutdown privilege for this process.
900 ::AdjustTokenPrivileges(hToken
, FALSE
, &tkp
, 0,
901 (PTOKEN_PRIVILEGES
)NULL
, 0);
903 // Cannot test the return value of AdjustTokenPrivileges.
904 bOK
= ::GetLastError() == ERROR_SUCCESS
;
910 UINT flags
= EWX_SHUTDOWN
| EWX_FORCE
;
913 case wxSHUTDOWN_POWEROFF
:
914 flags
|= EWX_POWEROFF
;
917 case wxSHUTDOWN_REBOOT
:
922 wxFAIL_MSG( _T("unknown wxShutdown() flag") );
926 bOK
= ::ExitWindowsEx(flags
, 0) != 0;
935 // ----------------------------------------------------------------------------
937 // ----------------------------------------------------------------------------
939 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
940 long wxGetFreeMemory()
942 #if defined(__WIN32__) && !defined(__BORLANDC__)
943 MEMORYSTATUS memStatus
;
944 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
945 GlobalMemoryStatus(&memStatus
);
946 return memStatus
.dwAvailPhys
;
948 return (long)GetFreeSpace(0);
952 unsigned long wxGetProcessId()
955 return ::GetCurrentProcessId();
964 ::MessageBeep((UINT
)-1); // default sound
967 wxString
wxGetOsDescription()
975 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
976 if ( ::GetVersionEx(&info
) )
978 switch ( info
.dwPlatformId
)
980 case VER_PLATFORM_WIN32s
:
981 str
= _("Win32s on Windows 3.1");
984 case VER_PLATFORM_WIN32_WINDOWS
:
985 str
.Printf(_("Windows 9%c"),
986 info
.dwMinorVersion
== 0 ? _T('5') : _T('8'));
987 if ( !wxIsEmpty(info
.szCSDVersion
) )
989 str
<< _T(" (") << info
.szCSDVersion
<< _T(')');
993 case VER_PLATFORM_WIN32_NT
:
994 str
.Printf(_T("Windows NT %lu.%lu (build %lu"),
998 if ( !wxIsEmpty(info
.szCSDVersion
) )
1000 str
<< _T(", ") << info
.szCSDVersion
;
1008 wxFAIL_MSG( _T("GetVersionEx() failed") ); // should never happen
1013 return _("Windows 3.1");
1017 wxToolkitInfo
& wxAppTraits::GetToolkitInfo()
1019 // cache the version info, it's not going to change
1021 // NB: this is MT-safe, we may use these static vars from different threads
1022 // but as they always have the same value it doesn't matter
1023 static int s_ver
= -1,
1033 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1034 if ( ::GetVersionEx(&info
) )
1036 s_major
= info
.dwMajorVersion
;
1037 s_minor
= info
.dwMinorVersion
;
1039 switch ( info
.dwPlatformId
)
1041 case VER_PLATFORM_WIN32s
:
1045 case VER_PLATFORM_WIN32_WINDOWS
:
1049 case VER_PLATFORM_WIN32_NT
:
1050 s_ver
= wxWINDOWS_NT
;
1053 case VER_PLATFORM_WIN32_CE
:
1054 s_ver
= wxWINDOWS_CE
;
1061 static wxToolkitInfo info
;
1062 info
.versionMajor
= s_major
;
1063 info
.versionMinor
= s_minor
;
1065 info
.name
= _T("wxBase");
1069 // ----------------------------------------------------------------------------
1071 // ----------------------------------------------------------------------------
1073 void wxUsleep(unsigned long milliseconds
)
1075 ::Sleep(milliseconds
);
1078 void wxSleep(int nSecs
)
1080 wxUsleep(1000*nSecs
);
1083 // ----------------------------------------------------------------------------
1084 // font encoding <-> Win32 codepage conversion functions
1085 // ----------------------------------------------------------------------------
1087 extern WXDLLIMPEXP_BASE
long wxEncodingToCharset(wxFontEncoding encoding
)
1091 // although this function is supposed to return an exact match, do do
1092 // some mappings here for the most common case of "standard" encoding
1093 case wxFONTENCODING_SYSTEM
:
1094 return DEFAULT_CHARSET
;
1096 case wxFONTENCODING_ISO8859_1
:
1097 case wxFONTENCODING_ISO8859_15
:
1098 case wxFONTENCODING_CP1252
:
1099 return ANSI_CHARSET
;
1101 #if !defined(__WXMICROWIN__)
1102 // The following four fonts are multi-byte charsets
1103 case wxFONTENCODING_CP932
:
1104 return SHIFTJIS_CHARSET
;
1106 case wxFONTENCODING_CP936
:
1107 return GB2312_CHARSET
;
1109 case wxFONTENCODING_CP949
:
1110 return HANGUL_CHARSET
;
1112 case wxFONTENCODING_CP950
:
1113 return CHINESEBIG5_CHARSET
;
1115 // The rest are single byte encodings
1116 case wxFONTENCODING_CP1250
:
1117 return EASTEUROPE_CHARSET
;
1119 case wxFONTENCODING_CP1251
:
1120 return RUSSIAN_CHARSET
;
1122 case wxFONTENCODING_CP1253
:
1123 return GREEK_CHARSET
;
1125 case wxFONTENCODING_CP1254
:
1126 return TURKISH_CHARSET
;
1128 case wxFONTENCODING_CP1255
:
1129 return HEBREW_CHARSET
;
1131 case wxFONTENCODING_CP1256
:
1132 return ARABIC_CHARSET
;
1134 case wxFONTENCODING_CP1257
:
1135 return BALTIC_CHARSET
;
1137 case wxFONTENCODING_CP874
:
1138 return THAI_CHARSET
;
1139 #endif // !__WXMICROWIN__
1141 case wxFONTENCODING_CP437
:
1145 // no way to translate this encoding into a Windows charset
1150 // we have 2 versions of wxCharsetToCodepage(): the old one which directly
1151 // looks up the vlaues in the registry and the new one which is more
1152 // politically correct and has more chances to work on other Windows versions
1153 // as well but the old version is still needed for !wxUSE_FONTMAP case
1156 #include "wx/fontmap.h"
1158 extern WXDLLIMPEXP_BASE
long wxEncodingToCodepage(wxFontEncoding encoding
)
1160 // translate encoding into the Windows CHARSET
1161 long charset
= wxEncodingToCharset(encoding
);
1162 if ( charset
== -1 )
1165 // translate CHARSET to code page
1166 CHARSETINFO csetInfo
;
1167 if ( !::TranslateCharsetInfo((DWORD
*)(DWORD
)charset
,
1171 wxLogLastError(_T("TranslateCharsetInfo(TCI_SRCCHARSET)"));
1176 return csetInfo
.ciACP
;
1179 extern long wxCharsetToCodepage(const wxChar
*name
)
1181 // first get the font encoding for this charset
1185 wxFontEncoding enc
= wxFontMapper::Get()->CharsetToEncoding(name
, FALSE
);
1186 if ( enc
== wxFONTENCODING_SYSTEM
)
1189 // the use the helper function
1190 return wxEncodingToCodepage(enc
);
1193 #else // !wxUSE_FONTMAP
1195 #include "wx/msw/registry.h"
1197 // this should work if Internet Exploiter is installed
1198 extern long wxCharsetToCodepage(const wxChar
*name
)
1205 wxString
path(wxT("MIME\\Database\\Charset\\"));
1208 // follow the alias loop
1211 wxRegKey
key(wxRegKey::HKCR
, path
+ cn
);
1216 // two cases: either there's an AliasForCharset string,
1217 // or there are Codepage and InternetEncoding dwords.
1218 // The InternetEncoding gives us the actual encoding,
1219 // the Codepage just says which Windows character set to
1220 // use when displaying the data.
1221 if (key
.HasValue(wxT("InternetEncoding")) &&
1222 key
.QueryValue(wxT("InternetEncoding"), &CP
))
1225 // no encoding, see if it's an alias
1226 if (!key
.HasValue(wxT("AliasForCharset")) ||
1227 !key
.QueryValue(wxT("AliasForCharset"), cn
))
1234 #endif // wxUSE_FONTMAP/!wxUSE_FONTMAP
1237 Creates a hidden window with supplied window proc registering the class for
1238 it if necesssary (i.e. the first time only). Caller is responsible for
1239 destroying the window and unregistering the class (note that this must be
1240 done because wxWindows may be used as a DLL and so may be loaded/unloaded
1241 multiple times into/from the same process so we cna't rely on automatic
1242 Windows class unregistration).
1244 pclassname is a pointer to a caller stored classname, which must initially be
1245 NULL. classname is the desired wndclass classname. If function succesfully
1246 registers the class, pclassname will be set to classname.
1248 extern "C" WXDLLIMPEXP_BASE HWND
1249 wxCreateHiddenWindow(LPCTSTR
*pclassname
, LPCTSTR classname
, WNDPROC wndproc
)
1251 wxCHECK_MSG( classname
&& pclassname
&& wndproc
, NULL
,
1252 _T("NULL parameter in wxCreateHiddenWindow") );
1254 // register the class fi we need to first
1255 if ( *pclassname
== NULL
)
1258 wxZeroMemory(wndclass
);
1260 wndclass
.lpfnWndProc
= wndproc
;
1261 wndclass
.hInstance
= wxGetInstance();
1262 wndclass
.lpszClassName
= classname
;
1264 if ( !::RegisterClass(&wndclass
) )
1266 wxLogLastError(wxT("RegisterClass() in wxCreateHiddenWindow"));
1271 *pclassname
= classname
;
1274 // next create the window
1275 HWND hwnd
= ::CreateWindow
1289 wxLogLastError(wxT("CreateWindow() in wxCreateHiddenWindow"));