/[pcsx2_0.9.7]/branch/r3113_0.9.7_beta/3rdparty/wxWidgets/src/msw/utils.cpp
ViewVC logotype

Contents of /branch/r3113_0.9.7_beta/3rdparty/wxWidgets/src/msw/utils.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (show annotations) (download)
Tue Sep 7 03:29:01 2010 UTC (9 years, 11 months ago) by william
File size: 47802 byte(s)
branching from upstream revision (http://pcsx2.googlecode.com/svn/trunk
): r3113 to
https://svn.netsolutions.dnsalias.com/websvn/ps2/pcsx2/pcsx2_0.9.7/branch/r3113_0.9.7_beta
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/utils.cpp
3 // Purpose: Various utilities
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id: utils.cpp 53784 2008-05-27 15:48:23Z VZ $
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #ifndef WX_PRECOMP
28 #include "wx/msw/missing.h" // CHARSET_HANGUL
29 #include "wx/utils.h"
30 #include "wx/app.h"
31 #include "wx/intl.h"
32 #include "wx/log.h"
33 #include "wx/timer.h"
34 #endif //WX_PRECOMP
35
36 #include "wx/msw/registry.h"
37 #include "wx/apptrait.h"
38 #include "wx/dynlib.h"
39 #include "wx/dynload.h"
40 #include "wx/scopeguard.h"
41
42 #include "wx/confbase.h" // for wxExpandEnvVars()
43
44 #include "wx/msw/private.h" // includes <windows.h>
45
46 #if defined(__CYGWIN__)
47 //CYGWIN gives annoying warning about runtime stuff if we don't do this
48 # define USE_SYS_TYPES_FD_SET
49 # include <sys/types.h>
50 #endif
51
52 // Doesn't work with Cygwin at present
53 #if wxUSE_SOCKETS && (defined(__GNUWIN32_OLD__) || defined(__WXWINCE__) || defined(__CYGWIN32__))
54 // apparently we need to include winsock.h to get WSADATA and other stuff
55 // used in wxGetFullHostName() with the old mingw32 versions
56 #include <winsock.h>
57 #endif
58
59 #if !defined(__GNUWIN32__) && !defined(__SALFORDC__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
60 #include <direct.h>
61
62 #ifndef __MWERKS__
63 #include <dos.h>
64 #endif
65 #endif //GNUWIN32
66
67 #if defined(__CYGWIN__)
68 #include <sys/unistd.h>
69 #include <sys/stat.h>
70 #include <sys/cygwin.h> // for cygwin_conv_to_full_win32_path()
71 #endif //GNUWIN32
72
73 #ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
74 // this (3.1 I believe) and how to test for it.
75 // If this works for Borland 4.0 as well, then no worries.
76 #include <dir.h>
77 #endif
78
79 // VZ: there is some code using NetXXX() functions to get the full user name:
80 // I don't think it's a good idea because they don't work under Win95 and
81 // seem to return the same as wxGetUserId() under NT. If you really want
82 // to use them, just #define USE_NET_API
83 #undef USE_NET_API
84
85 #ifdef USE_NET_API
86 #include <lm.h>
87 #endif // USE_NET_API
88
89 #if defined(__WIN32__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
90 #ifndef __UNIX__
91 #include <io.h>
92 #endif
93
94 #ifndef __GNUWIN32__
95 #include <shellapi.h>
96 #endif
97 #endif
98
99 #ifndef __WATCOMC__
100 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
101 #include <errno.h>
102 #endif
103 #endif
104
105 // For wxKillAllChildren
106 #include <tlhelp32.h>
107
108 // ----------------------------------------------------------------------------
109 // constants
110 // ----------------------------------------------------------------------------
111
112 // In the WIN.INI file
113 #if (!defined(USE_NET_API) && !defined(__WXWINCE__)) || defined(__WXMICROWIN__)
114 static const wxChar WX_SECTION[] = wxT("wxWindows");
115 #endif
116
117 #if (!defined(USE_NET_API) && !defined(__WXWINCE__))
118 static const wxChar eUSERNAME[] = wxT("UserName");
119 #endif
120
121 // ============================================================================
122 // implementation
123 // ============================================================================
124
125 // ----------------------------------------------------------------------------
126 // get host name and related
127 // ----------------------------------------------------------------------------
128
129 // Get hostname only (without domain name)
130 bool wxGetHostName(wxChar *WXUNUSED_IN_WINCE(buf),
131 int WXUNUSED_IN_WINCE(maxSize))
132 {
133 #if defined(__WXWINCE__)
134 // TODO-CE
135 return false;
136 #elif defined(__WIN32__) && !defined(__WXMICROWIN__)
137 DWORD nSize = maxSize;
138 if ( !::GetComputerName(buf, &nSize) )
139 {
140 wxLogLastError(wxT("GetComputerName"));
141
142 return false;
143 }
144
145 return true;
146 #else
147 wxChar *sysname;
148 const wxChar *default_host = wxT("noname");
149
150 if ((sysname = wxGetenv(wxT("SYSTEM_NAME"))) == NULL) {
151 GetProfileString(WX_SECTION, eHOSTNAME, default_host, buf, maxSize - 1);
152 } else
153 wxStrncpy(buf, sysname, maxSize - 1);
154 buf[maxSize] = wxT('\0');
155 return *buf ? true : false;
156 #endif
157 }
158
159 // get full hostname (with domain name if possible)
160 bool wxGetFullHostName(wxChar *buf, int maxSize)
161 {
162 #if !defined( __WXMICROWIN__) && wxUSE_DYNAMIC_LOADER && wxUSE_SOCKETS
163 // TODO should use GetComputerNameEx() when available
164
165 // we don't want to always link with Winsock DLL as we might not use it at
166 // all, so load it dynamically here if needed (and don't complain if it is
167 // missing, we handle this)
168 wxLogNull noLog;
169
170 wxDynamicLibrary dllWinsock(_T("ws2_32.dll"), wxDL_VERBATIM);
171 if ( dllWinsock.IsLoaded() )
172 {
173 typedef int (PASCAL *WSAStartup_t)(WORD, WSADATA *);
174 typedef int (PASCAL *gethostname_t)(char *, int);
175 typedef hostent* (PASCAL *gethostbyname_t)(const char *);
176 typedef hostent* (PASCAL *gethostbyaddr_t)(const char *, int , int);
177 typedef int (PASCAL *WSACleanup_t)(void);
178
179 #define LOAD_WINSOCK_FUNC(func) \
180 func ## _t \
181 pfn ## func = (func ## _t)dllWinsock.GetSymbol(_T(#func))
182
183 LOAD_WINSOCK_FUNC(WSAStartup);
184
185 WSADATA wsa;
186 if ( pfnWSAStartup && pfnWSAStartup(MAKEWORD(1, 1), &wsa) == 0 )
187 {
188 LOAD_WINSOCK_FUNC(gethostname);
189
190 wxString host;
191 if ( pfngethostname )
192 {
193 char bufA[256];
194 if ( pfngethostname(bufA, WXSIZEOF(bufA)) == 0 )
195 {
196 // gethostname() won't usually include the DNS domain name,
197 // for this we need to work a bit more
198 if ( !strchr(bufA, '.') )
199 {
200 LOAD_WINSOCK_FUNC(gethostbyname);
201
202 struct hostent *pHostEnt = pfngethostbyname
203 ? pfngethostbyname(bufA)
204 : NULL;
205
206 if ( pHostEnt )
207 {
208 // Windows will use DNS internally now
209 LOAD_WINSOCK_FUNC(gethostbyaddr);
210
211 pHostEnt = pfngethostbyaddr
212 ? pfngethostbyaddr(pHostEnt->h_addr,
213 4, AF_INET)
214 : NULL;
215 }
216
217 if ( pHostEnt )
218 {
219 host = wxString::FromAscii(pHostEnt->h_name);
220 }
221 }
222 }
223 }
224
225 LOAD_WINSOCK_FUNC(WSACleanup);
226 if ( pfnWSACleanup )
227 pfnWSACleanup();
228
229
230 if ( !host.empty() )
231 {
232 wxStrncpy(buf, host, maxSize);
233
234 return true;
235 }
236 }
237 }
238 #endif // !__WXMICROWIN__
239
240 return wxGetHostName(buf, maxSize);
241 }
242
243 // Get user ID e.g. jacs
244 bool wxGetUserId(wxChar *WXUNUSED_IN_WINCE(buf),
245 int WXUNUSED_IN_WINCE(maxSize))
246 {
247 #if defined(__WXWINCE__)
248 // TODO-CE
249 return false;
250 #elif defined(__WIN32__) && !defined(__WXMICROWIN__)
251 DWORD nSize = maxSize;
252 if ( ::GetUserName(buf, &nSize) == 0 )
253 {
254 // actually, it does happen on Win9x if the user didn't log on
255 DWORD res = ::GetEnvironmentVariable(wxT("username"), buf, maxSize);
256 if ( res == 0 )
257 {
258 // not found
259 return false;
260 }
261 }
262
263 return true;
264 #else // __WXMICROWIN__
265 wxChar *user;
266 const wxChar *default_id = wxT("anonymous");
267
268 // Can't assume we have NIS (PC-NFS) or some other ID daemon
269 // So we ...
270 if ( (user = wxGetenv(wxT("USER"))) == NULL &&
271 (user = wxGetenv(wxT("LOGNAME"))) == NULL )
272 {
273 // Use wxWidgets configuration data (comming soon)
274 GetProfileString(WX_SECTION, eUSERID, default_id, buf, maxSize - 1);
275 }
276 else
277 {
278 wxStrncpy(buf, user, maxSize - 1);
279 }
280
281 return *buf ? true : false;
282 #endif
283 }
284
285 // Get user name e.g. Julian Smart
286 bool wxGetUserName(wxChar *buf, int maxSize)
287 {
288 wxCHECK_MSG( buf && ( maxSize > 0 ), false,
289 _T("empty buffer in wxGetUserName") );
290 #if defined(__WXWINCE__)
291 wxLogNull noLog;
292 wxRegKey key(wxRegKey::HKCU, wxT("ControlPanel\\Owner"));
293 if(!key.Open(wxRegKey::Read))
294 return false;
295 wxString name;
296 if(!key.QueryValue(wxT("Owner"),name))
297 return false;
298 wxStrncpy(buf, name.c_str(), maxSize-1);
299 buf[maxSize-1] = _T('\0');
300 return true;
301 #elif defined(USE_NET_API)
302 CHAR szUserName[256];
303 if ( !wxGetUserId(szUserName, WXSIZEOF(szUserName)) )
304 return false;
305
306 // TODO how to get the domain name?
307 CHAR *szDomain = "";
308
309 // the code is based on the MSDN example (also see KB article Q119670)
310 WCHAR wszUserName[256]; // Unicode user name
311 WCHAR wszDomain[256];
312 LPBYTE ComputerName;
313
314 USER_INFO_2 *ui2; // User structure
315
316 // Convert ANSI user name and domain to Unicode
317 MultiByteToWideChar( CP_ACP, 0, szUserName, strlen(szUserName)+1,
318 wszUserName, WXSIZEOF(wszUserName) );
319 MultiByteToWideChar( CP_ACP, 0, szDomain, strlen(szDomain)+1,
320 wszDomain, WXSIZEOF(wszDomain) );
321
322 // Get the computer name of a DC for the domain.
323 if ( NetGetDCName( NULL, wszDomain, &ComputerName ) != NERR_Success )
324 {
325 wxLogError(wxT("Can not find domain controller"));
326
327 goto error;
328 }
329
330 // Look up the user on the DC
331 NET_API_STATUS status = NetUserGetInfo( (LPWSTR)ComputerName,
332 (LPWSTR)&wszUserName,
333 2, // level - we want USER_INFO_2
334 (LPBYTE *) &ui2 );
335 switch ( status )
336 {
337 case NERR_Success:
338 // ok
339 break;
340
341 case NERR_InvalidComputer:
342 wxLogError(wxT("Invalid domain controller name."));
343
344 goto error;
345
346 case NERR_UserNotFound:
347 wxLogError(wxT("Invalid user name '%s'."), szUserName);
348
349 goto error;
350
351 default:
352 wxLogSysError(wxT("Can't get information about user"));
353
354 goto error;
355 }
356
357 // Convert the Unicode full name to ANSI
358 WideCharToMultiByte( CP_ACP, 0, ui2->usri2_full_name, -1,
359 buf, maxSize, NULL, NULL );
360
361 return true;
362
363 error:
364 wxLogError(wxT("Couldn't look up full user name."));
365
366 return false;
367 #else // !USE_NET_API
368 // Could use NIS, MS-Mail or other site specific programs
369 // Use wxWidgets configuration data
370 bool ok = GetProfileString(WX_SECTION, eUSERNAME, wxEmptyString, buf, maxSize - 1) != 0;
371 if ( !ok )
372 {
373 ok = wxGetUserId(buf, maxSize);
374 }
375
376 if ( !ok )
377 {
378 wxStrncpy(buf, wxT("Unknown User"), maxSize);
379 }
380
381 return true;
382 #endif // Win32/16
383 }
384
385 const wxChar* wxGetHomeDir(wxString *pstr)
386 {
387 wxString& strDir = *pstr;
388
389 // first branch is for Cygwin
390 #if defined(__UNIX__) && !defined(__WINE__)
391 const wxChar *szHome = wxGetenv("HOME");
392 if ( szHome == NULL ) {
393 // we're homeless...
394 wxLogWarning(_("can't find user's HOME, using current directory."));
395 strDir = wxT(".");
396 }
397 else
398 strDir = szHome;
399
400 // add a trailing slash if needed
401 if ( strDir.Last() != wxT('/') )
402 strDir << wxT('/');
403
404 #ifdef __CYGWIN__
405 // Cygwin returns unix type path but that does not work well
406 static wxChar windowsPath[MAX_PATH];
407 cygwin_conv_to_full_win32_path(strDir, windowsPath);
408 strDir = windowsPath;
409 #endif
410 #elif defined(__WXWINCE__)
411 strDir = wxT("\\");
412 #else
413 strDir.clear();
414
415 // If we have a valid HOME directory, as is used on many machines that
416 // have unix utilities on them, we should use that.
417 const wxChar *szHome = wxGetenv(wxT("HOME"));
418
419 if ( szHome != NULL )
420 {
421 strDir = szHome;
422 }
423 else // no HOME, try HOMEDRIVE/PATH
424 {
425 szHome = wxGetenv(wxT("HOMEDRIVE"));
426 if ( szHome != NULL )
427 strDir << szHome;
428 szHome = wxGetenv(wxT("HOMEPATH"));
429
430 if ( szHome != NULL )
431 {
432 strDir << szHome;
433
434 // the idea is that under NT these variables have default values
435 // of "%systemdrive%:" and "\\". As we don't want to create our
436 // config files in the root directory of the system drive, we will
437 // create it in our program's dir. However, if the user took care
438 // to set HOMEPATH to something other than "\\", we suppose that he
439 // knows what he is doing and use the supplied value.
440 if ( wxStrcmp(szHome, wxT("\\")) == 0 )
441 strDir.clear();
442 }
443 }
444
445 if ( strDir.empty() )
446 {
447 // If we have a valid USERPROFILE directory, as is the case in
448 // Windows NT, 2000 and XP, we should use that as our home directory.
449 szHome = wxGetenv(wxT("USERPROFILE"));
450
451 if ( szHome != NULL )
452 strDir = szHome;
453 }
454
455 if ( !strDir.empty() )
456 {
457 // sometimes the value of HOME may be "%USERPROFILE%", so reexpand the
458 // value once again, it shouldn't hurt anyhow
459 strDir = wxExpandEnvVars(strDir);
460 }
461 else // fall back to the program directory
462 {
463 // extract the directory component of the program file name
464 wxSplitPath(wxGetFullModuleName(), &strDir, NULL, NULL);
465 }
466 #endif // UNIX/Win
467
468 return strDir.c_str();
469 }
470
471 wxChar *wxGetUserHome(const wxString& WXUNUSED(user))
472 {
473 // VZ: the old code here never worked for user != "" anyhow! Moreover, it
474 // returned sometimes a malloc()'d pointer, sometimes a pointer to a
475 // static buffer and sometimes I don't even know what.
476 static wxString s_home;
477
478 return (wxChar *)wxGetHomeDir(&s_home);
479 }
480
481 bool wxGetDiskSpace(const wxString& WXUNUSED_IN_WINCE(path),
482 wxDiskspaceSize_t *WXUNUSED_IN_WINCE(pTotal),
483 wxDiskspaceSize_t *WXUNUSED_IN_WINCE(pFree))
484 {
485 #ifdef __WXWINCE__
486 // TODO-CE
487 return false;
488 #else
489 if ( path.empty() )
490 return false;
491
492 // old w32api don't have ULARGE_INTEGER
493 #if defined(__WIN32__) && \
494 (!defined(__GNUWIN32__) || wxCHECK_W32API_VERSION( 0, 3 ))
495 // GetDiskFreeSpaceEx() is not available under original Win95, check for
496 // it
497 typedef BOOL (WINAPI *GetDiskFreeSpaceEx_t)(LPCTSTR,
498 PULARGE_INTEGER,
499 PULARGE_INTEGER,
500 PULARGE_INTEGER);
501
502 GetDiskFreeSpaceEx_t
503 pGetDiskFreeSpaceEx = (GetDiskFreeSpaceEx_t)::GetProcAddress
504 (
505 ::GetModuleHandle(_T("kernel32.dll")),
506 #if wxUSE_UNICODE
507 "GetDiskFreeSpaceExW"
508 #else
509 "GetDiskFreeSpaceExA"
510 #endif
511 );
512
513 if ( pGetDiskFreeSpaceEx )
514 {
515 ULARGE_INTEGER bytesFree, bytesTotal;
516
517 // may pass the path as is, GetDiskFreeSpaceEx() is smart enough
518 if ( !pGetDiskFreeSpaceEx(path,
519 &bytesFree,
520 &bytesTotal,
521 NULL) )
522 {
523 wxLogLastError(_T("GetDiskFreeSpaceEx"));
524
525 return false;
526 }
527
528 // ULARGE_INTEGER is a union of a 64 bit value and a struct containing
529 // two 32 bit fields which may be or may be not named - try to make it
530 // compile in all cases
531 #if defined(__BORLANDC__) && !defined(_ANONYMOUS_STRUCT)
532 #define UL(ul) ul.u
533 #else // anon union
534 #define UL(ul) ul
535 #endif
536 if ( pTotal )
537 {
538 #if wxUSE_LONGLONG
539 *pTotal = wxDiskspaceSize_t(UL(bytesTotal).HighPart, UL(bytesTotal).LowPart);
540 #else
541 *pTotal = wxDiskspaceSize_t(UL(bytesTotal).LowPart);
542 #endif
543 }
544
545 if ( pFree )
546 {
547 #if wxUSE_LONGLONG
548 *pFree = wxLongLong(UL(bytesFree).HighPart, UL(bytesFree).LowPart);
549 #else
550 *pFree = wxDiskspaceSize_t(UL(bytesFree).LowPart);
551 #endif
552 }
553 }
554 else
555 #endif // Win32
556 {
557 // there's a problem with drives larger than 2GB, GetDiskFreeSpaceEx()
558 // should be used instead - but if it's not available, fall back on
559 // GetDiskFreeSpace() nevertheless...
560
561 DWORD lSectorsPerCluster,
562 lBytesPerSector,
563 lNumberOfFreeClusters,
564 lTotalNumberOfClusters;
565
566 // FIXME: this is wrong, we should extract the root drive from path
567 // instead, but this is the job for wxFileName...
568 if ( !::GetDiskFreeSpace(path,
569 &lSectorsPerCluster,
570 &lBytesPerSector,
571 &lNumberOfFreeClusters,
572 &lTotalNumberOfClusters) )
573 {
574 wxLogLastError(_T("GetDiskFreeSpace"));
575
576 return false;
577 }
578
579 wxDiskspaceSize_t lBytesPerCluster = (wxDiskspaceSize_t) lSectorsPerCluster;
580 lBytesPerCluster *= lBytesPerSector;
581
582 if ( pTotal )
583 {
584 *pTotal = lBytesPerCluster;
585 *pTotal *= lTotalNumberOfClusters;
586 }
587
588 if ( pFree )
589 {
590 *pFree = lBytesPerCluster;
591 *pFree *= lNumberOfFreeClusters;
592 }
593 }
594
595 return true;
596 #endif
597 // __WXWINCE__
598 }
599
600 // ----------------------------------------------------------------------------
601 // env vars
602 // ----------------------------------------------------------------------------
603
604 bool wxGetEnv(const wxString& WXUNUSED_IN_WINCE(var),
605 wxString *WXUNUSED_IN_WINCE(value))
606 {
607 #ifdef __WXWINCE__
608 // no environment variables under CE
609 return false;
610 #else // Win32
611 // first get the size of the buffer
612 DWORD dwRet = ::GetEnvironmentVariable(var, NULL, 0);
613 if ( !dwRet )
614 {
615 // this means that there is no such variable
616 return false;
617 }
618
619 if ( value )
620 {
621 (void)::GetEnvironmentVariable(var, wxStringBuffer(*value, dwRet),
622 dwRet);
623 }
624
625 return true;
626 #endif // WinCE/32
627 }
628
629 bool wxSetEnv(const wxString& WXUNUSED_IN_WINCE(var),
630 const wxChar *WXUNUSED_IN_WINCE(value))
631 {
632 // some compilers have putenv() or _putenv() or _wputenv() but it's better
633 // to always use Win32 function directly instead of dealing with them
634 #ifdef __WXWINCE__
635 // no environment variables under CE
636 return false;
637 #else
638 if ( !::SetEnvironmentVariable(var, value) )
639 {
640 wxLogLastError(_T("SetEnvironmentVariable"));
641
642 return false;
643 }
644
645 return true;
646 #endif
647 }
648
649 // ----------------------------------------------------------------------------
650 // process management
651 // ----------------------------------------------------------------------------
652
653 // structure used to pass parameters from wxKill() to wxEnumFindByPidProc()
654 struct wxFindByPidParams
655 {
656 wxFindByPidParams() { hwnd = 0; pid = 0; }
657
658 // the HWND used to return the result
659 HWND hwnd;
660
661 // the PID we're looking from
662 DWORD pid;
663
664 DECLARE_NO_COPY_CLASS(wxFindByPidParams)
665 };
666
667 // wxKill helper: EnumWindows() callback which is used to find the first (top
668 // level) window belonging to the given process
669 BOOL CALLBACK wxEnumFindByPidProc(HWND hwnd, LPARAM lParam)
670 {
671 DWORD pid;
672 (void)::GetWindowThreadProcessId(hwnd, &pid);
673
674 wxFindByPidParams *params = (wxFindByPidParams *)lParam;
675 if ( pid == params->pid )
676 {
677 // remember the window we found
678 params->hwnd = hwnd;
679
680 // return FALSE to stop the enumeration
681 return FALSE;
682 }
683
684 // continue enumeration
685 return TRUE;
686 }
687
688 int wxKillAllChildren(long pid, wxSignal sig, wxKillError *krc);
689
690 int wxKill(long pid, wxSignal sig, wxKillError *krc, int flags)
691 {
692 if (flags & wxKILL_CHILDREN)
693 wxKillAllChildren(pid, sig, krc);
694
695 // get the process handle to operate on
696 HANDLE hProcess = ::OpenProcess(SYNCHRONIZE |
697 PROCESS_TERMINATE |
698 PROCESS_QUERY_INFORMATION,
699 FALSE, // not inheritable
700 (DWORD)pid);
701 if ( hProcess == NULL )
702 {
703 if ( krc )
704 {
705 // recognize wxKILL_ACCESS_DENIED as special because this doesn't
706 // mean that the process doesn't exist and this is important for
707 // wxProcess::Exists()
708 *krc = ::GetLastError() == ERROR_ACCESS_DENIED
709 ? wxKILL_ACCESS_DENIED
710 : wxKILL_NO_PROCESS;
711 }
712
713 return -1;
714 }
715
716 wxON_BLOCK_EXIT1(::CloseHandle, hProcess);
717
718 bool ok = true;
719 switch ( sig )
720 {
721 case wxSIGKILL:
722 // kill the process forcefully returning -1 as error code
723 if ( !::TerminateProcess(hProcess, (UINT)-1) )
724 {
725 wxLogSysError(_("Failed to kill process %d"), pid);
726
727 if ( krc )
728 {
729 // this is not supposed to happen if we could open the
730 // process
731 *krc = wxKILL_ERROR;
732 }
733
734 ok = false;
735 }
736 break;
737
738 case wxSIGNONE:
739 // do nothing, we just want to test for process existence
740 if ( krc )
741 *krc = wxKILL_OK;
742 return 0;
743
744 default:
745 // any other signal means "terminate"
746 {
747 wxFindByPidParams params;
748 params.pid = (DWORD)pid;
749
750 // EnumWindows() has nice semantics: it returns 0 if it found
751 // something or if an error occurred and non zero if it
752 // enumerated all the window
753 if ( !::EnumWindows(wxEnumFindByPidProc, (LPARAM)&params) )
754 {
755 // did we find any window?
756 if ( params.hwnd )
757 {
758 // tell the app to close
759 //
760 // NB: this is the harshest way, the app won't have an
761 // opportunity to save any files, for example, but
762 // this is probably what we want here. If not we
763 // can also use SendMesageTimeout(WM_CLOSE)
764 if ( !::PostMessage(params.hwnd, WM_QUIT, 0, 0) )
765 {
766 wxLogLastError(_T("PostMessage(WM_QUIT)"));
767 }
768 }
769 else // it was an error then
770 {
771 wxLogLastError(_T("EnumWindows"));
772
773 ok = false;
774 }
775 }
776 else // no windows for this PID
777 {
778 if ( krc )
779 *krc = wxKILL_ERROR;
780
781 ok = false;
782 }
783 }
784 }
785
786 // the return code
787 DWORD rc wxDUMMY_INITIALIZE(0);
788 if ( ok )
789 {
790 // as we wait for a short time, we can use just WaitForSingleObject()
791 // and not MsgWaitForMultipleObjects()
792 switch ( ::WaitForSingleObject(hProcess, 500 /* msec */) )
793 {
794 case WAIT_OBJECT_0:
795 // process terminated
796 if ( !::GetExitCodeProcess(hProcess, &rc) )
797 {
798 wxLogLastError(_T("GetExitCodeProcess"));
799 }
800 break;
801
802 default:
803 wxFAIL_MSG( _T("unexpected WaitForSingleObject() return") );
804 // fall through
805
806 case WAIT_FAILED:
807 wxLogLastError(_T("WaitForSingleObject"));
808 // fall through
809
810 case WAIT_TIMEOUT:
811 if ( krc )
812 *krc = wxKILL_ERROR;
813
814 rc = STILL_ACTIVE;
815 break;
816 }
817 }
818
819
820 // the return code is the same as from Unix kill(): 0 if killed
821 // successfully or -1 on error
822 if ( !ok || rc == STILL_ACTIVE )
823 return -1;
824
825 if ( krc )
826 *krc = wxKILL_OK;
827
828 return 0;
829 }
830
831 typedef HANDLE (WINAPI *CreateToolhelp32Snapshot_t)(DWORD,DWORD);
832 typedef BOOL (WINAPI *Process32_t)(HANDLE,LPPROCESSENTRY32);
833
834 CreateToolhelp32Snapshot_t lpfCreateToolhelp32Snapshot;
835 Process32_t lpfProcess32First, lpfProcess32Next;
836
837 static void InitToolHelp32()
838 {
839 static bool s_initToolHelpDone = false;
840
841 if (s_initToolHelpDone)
842 return;
843
844 s_initToolHelpDone = true;
845
846 lpfCreateToolhelp32Snapshot = NULL;
847 lpfProcess32First = NULL;
848 lpfProcess32Next = NULL;
849
850 #if wxUSE_DYNLIB_CLASS
851
852 wxDynamicLibrary dllKernel(_T("kernel32.dll"), wxDL_VERBATIM);
853
854 // Get procedure addresses.
855 // We are linking to these functions of Kernel32
856 // explicitly, because otherwise a module using
857 // this code would fail to load under Windows NT,
858 // which does not have the Toolhelp32
859 // functions in the Kernel 32.
860 lpfCreateToolhelp32Snapshot =
861 (CreateToolhelp32Snapshot_t)dllKernel.RawGetSymbol(_T("CreateToolhelp32Snapshot"));
862
863 lpfProcess32First =
864 (Process32_t)dllKernel.RawGetSymbol(_T("Process32First"));
865
866 lpfProcess32Next =
867 (Process32_t)dllKernel.RawGetSymbol(_T("Process32Next"));
868
869 #endif // wxUSE_DYNLIB_CLASS
870 }
871
872 // By John Skiff
873 int wxKillAllChildren(long pid, wxSignal sig, wxKillError *krc)
874 {
875 InitToolHelp32();
876
877 if (krc)
878 *krc = wxKILL_OK;
879
880 // If not implemented for this platform (e.g. NT 4.0), silently ignore
881 if (!lpfCreateToolhelp32Snapshot || !lpfProcess32First || !lpfProcess32Next)
882 return 0;
883
884 // Take a snapshot of all processes in the system.
885 HANDLE hProcessSnap = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
886 if (hProcessSnap == INVALID_HANDLE_VALUE) {
887 if (krc)
888 *krc = wxKILL_ERROR;
889 return -1;
890 }
891
892 //Fill in the size of the structure before using it.
893 PROCESSENTRY32 pe;
894 wxZeroMemory(pe);
895 pe.dwSize = sizeof(PROCESSENTRY32);
896
897 // Walk the snapshot of the processes, and for each process,
898 // kill it if its parent is pid.
899 if (!lpfProcess32First(hProcessSnap, &pe)) {
900 // Can't get first process.
901 if (krc)
902 *krc = wxKILL_ERROR;
903 CloseHandle (hProcessSnap);
904 return -1;
905 }
906
907 do {
908 if (pe.th32ParentProcessID == (DWORD) pid) {
909 if (wxKill(pe.th32ProcessID, sig, krc))
910 return -1;
911 }
912 } while (lpfProcess32Next (hProcessSnap, &pe));
913
914
915 return 0;
916 }
917
918 // Execute a program in an Interactive Shell
919 bool wxShell(const wxString& command)
920 {
921 wxString cmd;
922
923 #ifdef __WXWINCE__
924 cmd = command;
925 #else
926 wxChar *shell = wxGetenv(wxT("COMSPEC"));
927 if ( !shell )
928 shell = (wxChar*) wxT("\\COMMAND.COM");
929
930 if ( !command )
931 {
932 // just the shell
933 cmd = shell;
934 }
935 else
936 {
937 // pass the command to execute to the command processor
938 cmd.Printf(wxT("%s /c %s"), shell, command.c_str());
939 }
940 #endif
941
942 return wxExecute(cmd, wxEXEC_SYNC) == 0;
943 }
944
945 // Shutdown or reboot the PC
946 bool wxShutdown(wxShutdownFlags WXUNUSED_IN_WINCE(wFlags))
947 {
948 #ifdef __WXWINCE__
949 // TODO-CE
950 return false;
951 #elif defined(__WIN32__)
952 bool bOK = true;
953
954 if ( wxGetOsVersion(NULL, NULL) == wxOS_WINDOWS_NT ) // if is NT or 2K
955 {
956 // Get a token for this process.
957 HANDLE hToken;
958 bOK = ::OpenProcessToken(GetCurrentProcess(),
959 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
960 &hToken) != 0;
961 if ( bOK )
962 {
963 TOKEN_PRIVILEGES tkp;
964
965 // Get the LUID for the shutdown privilege.
966 ::LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
967 &tkp.Privileges[0].Luid);
968
969 tkp.PrivilegeCount = 1; // one privilege to set
970 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
971
972 // Get the shutdown privilege for this process.
973 ::AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
974 (PTOKEN_PRIVILEGES)NULL, 0);
975
976 // Cannot test the return value of AdjustTokenPrivileges.
977 bOK = ::GetLastError() == ERROR_SUCCESS;
978 }
979 }
980
981 if ( bOK )
982 {
983 UINT flags = EWX_SHUTDOWN | EWX_FORCE;
984 switch ( wFlags )
985 {
986 case wxSHUTDOWN_POWEROFF:
987 flags |= EWX_POWEROFF;
988 break;
989
990 case wxSHUTDOWN_REBOOT:
991 flags |= EWX_REBOOT;
992 break;
993
994 default:
995 wxFAIL_MSG( _T("unknown wxShutdown() flag") );
996 return false;
997 }
998
999 bOK = ::ExitWindowsEx(flags, 0) != 0;
1000 }
1001
1002 return bOK;
1003 #endif // Win32/16
1004 }
1005
1006 // ----------------------------------------------------------------------------
1007 // misc
1008 // ----------------------------------------------------------------------------
1009
1010 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
1011 wxMemorySize wxGetFreeMemory()
1012 {
1013 #if defined(__WIN64__)
1014 MEMORYSTATUSEX memStatex;
1015 memStatex.dwLength = sizeof (memStatex);
1016 ::GlobalMemoryStatusEx (&memStatex);
1017 return (wxMemorySize)memStatex.ullAvailPhys;
1018 #else /* if defined(__WIN32__) */
1019 MEMORYSTATUS memStatus;
1020 memStatus.dwLength = sizeof(MEMORYSTATUS);
1021 ::GlobalMemoryStatus(&memStatus);
1022 return (wxMemorySize)memStatus.dwAvailPhys;
1023 #endif
1024 }
1025
1026 unsigned long wxGetProcessId()
1027 {
1028 return ::GetCurrentProcessId();
1029 }
1030
1031 // Emit a beeeeeep
1032 void wxBell()
1033 {
1034 ::MessageBeep((UINT)-1); // default sound
1035 }
1036
1037 bool wxIsDebuggerRunning()
1038 {
1039 #if wxUSE_DYNLIB_CLASS
1040 // IsDebuggerPresent() is not available under Win95, so load it dynamically
1041 wxDynamicLibrary dll(_T("kernel32.dll"), wxDL_VERBATIM);
1042
1043 typedef BOOL (WINAPI *IsDebuggerPresent_t)();
1044 if ( !dll.HasSymbol(_T("IsDebuggerPresent")) )
1045 {
1046 // no way to know, assume no
1047 return false;
1048 }
1049
1050 return (*(IsDebuggerPresent_t)dll.GetSymbol(_T("IsDebuggerPresent")))() != 0;
1051 #else
1052 return false;
1053 #endif
1054 }
1055
1056 // ----------------------------------------------------------------------------
1057 // OS version
1058 // ----------------------------------------------------------------------------
1059
1060 wxString wxGetOsDescription()
1061 {
1062 wxString str;
1063
1064 OSVERSIONINFO info;
1065 wxZeroMemory(info);
1066
1067 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
1068 if ( ::GetVersionEx(&info) )
1069 {
1070 switch ( info.dwPlatformId )
1071 {
1072 #ifdef VER_PLATFORM_WIN32_CE
1073 case VER_PLATFORM_WIN32_CE:
1074 str.Printf(_("Windows CE (%d.%d)"),
1075 info.dwMajorVersion,
1076 info.dwMinorVersion);
1077 break;
1078 #endif
1079 case VER_PLATFORM_WIN32s:
1080 str = _("Win32s on Windows 3.1");
1081 break;
1082
1083 case VER_PLATFORM_WIN32_WINDOWS:
1084 switch (info.dwMinorVersion)
1085 {
1086 case 0:
1087 if ( info.szCSDVersion[1] == 'B' ||
1088 info.szCSDVersion[1] == 'C' )
1089 {
1090 str = _("Windows 95 OSR2");
1091 }
1092 else
1093 {
1094 str = _("Windows 95");
1095 }
1096 break;
1097 case 10:
1098 if ( info.szCSDVersion[1] == 'B' ||
1099 info.szCSDVersion[1] == 'C' )
1100 {
1101 str = _("Windows 98 SE");
1102 }
1103 else
1104 {
1105 str = _("Windows 98");
1106 }
1107 break;
1108 case 90:
1109 str = _("Windows ME");
1110 break;
1111 default:
1112 str.Printf(_("Windows 9x (%d.%d)"),
1113 info.dwMajorVersion,
1114 info.dwMinorVersion);
1115 break;
1116 }
1117 if ( !wxIsEmpty(info.szCSDVersion) )
1118 {
1119 str << _T(" (") << info.szCSDVersion << _T(')');
1120 }
1121 break;
1122
1123 case VER_PLATFORM_WIN32_NT:
1124 switch ( info.dwMajorVersion )
1125 {
1126 case 5:
1127 switch ( info.dwMinorVersion )
1128 {
1129 case 0:
1130 str.Printf(_("Windows 2000 (build %lu"),
1131 info.dwBuildNumber);
1132 break;
1133
1134 case 1:
1135 str.Printf(_("Windows XP (build %lu"),
1136 info.dwBuildNumber);
1137 break;
1138
1139 case 2:
1140 str.Printf(_("Windows Server 2003 (build %lu"),
1141 info.dwBuildNumber);
1142 break;
1143 }
1144 break;
1145
1146 case 6:
1147 if ( info.dwMinorVersion == 0 )
1148 {
1149 str.Printf(_("Windows Vista (build %lu"),
1150 info.dwBuildNumber);
1151 }
1152 break;
1153 }
1154
1155 if ( str.empty() )
1156 {
1157 str.Printf(_("Windows NT %lu.%lu (build %lu"),
1158 info.dwMajorVersion,
1159 info.dwMinorVersion,
1160 info.dwBuildNumber);
1161 }
1162
1163 if ( !wxIsEmpty(info.szCSDVersion) )
1164 {
1165 str << _T(", ") << info.szCSDVersion;
1166 }
1167 str << _T(')');
1168 break;
1169 }
1170 }
1171 else
1172 {
1173 wxFAIL_MSG( _T("GetVersionEx() failed") ); // should never happen
1174 }
1175
1176 return str;
1177 }
1178
1179 bool wxIsPlatform64Bit()
1180 {
1181 #if defined(_WIN64)
1182 return true; // 64-bit programs run only on Win64
1183 #else // Win32
1184 // 32-bit programs run on both 32-bit and 64-bit Windows so check
1185 typedef BOOL (WINAPI *IsWow64Process_t)(HANDLE, BOOL *);
1186
1187 wxDynamicLibrary dllKernel32(_T("kernel32.dll"));
1188 IsWow64Process_t pfnIsWow64Process =
1189 (IsWow64Process_t)dllKernel32.RawGetSymbol(_T("IsWow64Process"));
1190
1191 BOOL wow64 = FALSE;
1192 if ( pfnIsWow64Process )
1193 {
1194 pfnIsWow64Process(::GetCurrentProcess(), &wow64);
1195 }
1196 //else: running under a system without Win64 support
1197
1198 return wow64 != FALSE;
1199 #endif // Win64/Win32
1200 }
1201
1202 wxOperatingSystemId wxGetOsVersion(int *verMaj, int *verMin)
1203 {
1204 OSVERSIONINFO info;
1205 wxZeroMemory(info);
1206
1207 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
1208 if ( ::GetVersionEx(&info) )
1209 {
1210 if (verMaj) *verMaj = info.dwMajorVersion;
1211 if (verMin) *verMin = info.dwMinorVersion;
1212 }
1213
1214 #if defined( __WXWINCE__ )
1215 return wxOS_WINDOWS_CE;
1216 #elif defined( __WXMICROWIN__ )
1217 return wxOS_WINDOWS_MICRO;
1218 #else
1219 switch ( info.dwPlatformId )
1220 {
1221 case VER_PLATFORM_WIN32_NT:
1222 return wxOS_WINDOWS_NT;
1223
1224 case VER_PLATFORM_WIN32_WINDOWS:
1225 return wxOS_WINDOWS_9X;
1226 }
1227
1228 return wxOS_UNKNOWN;
1229 #endif
1230 }
1231
1232 wxWinVersion wxGetWinVersion()
1233 {
1234 int verMaj,
1235 verMin;
1236 switch ( wxGetOsVersion(&verMaj, &verMin) )
1237 {
1238 case wxOS_WINDOWS_9X:
1239 if ( verMaj == 4 )
1240 {
1241 switch ( verMin )
1242 {
1243 case 0:
1244 return wxWinVersion_95;
1245
1246 case 10:
1247 return wxWinVersion_98;
1248
1249 case 90:
1250 return wxWinVersion_ME;
1251 }
1252 }
1253 break;
1254
1255 case wxOS_WINDOWS_NT:
1256 switch ( verMaj )
1257 {
1258 case 3:
1259 return wxWinVersion_NT3;
1260
1261 case 4:
1262 return wxWinVersion_NT4;
1263
1264 case 5:
1265 switch ( verMin )
1266 {
1267 case 0:
1268 return wxWinVersion_2000;
1269
1270 case 1:
1271 return wxWinVersion_XP;
1272
1273 case 2:
1274 return wxWinVersion_2003;
1275 }
1276 break;
1277
1278 case 6:
1279 return wxWinVersion_NT6;
1280 }
1281 break;
1282
1283 default:
1284 // Do nothing just to silence GCC warning
1285 break;
1286 }
1287
1288 return wxWinVersion_Unknown;
1289 }
1290
1291 // ----------------------------------------------------------------------------
1292 // sleep functions
1293 // ----------------------------------------------------------------------------
1294
1295 void wxMilliSleep(unsigned long milliseconds)
1296 {
1297 ::Sleep(milliseconds);
1298 }
1299
1300 void wxMicroSleep(unsigned long microseconds)
1301 {
1302 wxMilliSleep(microseconds/1000);
1303 }
1304
1305 void wxSleep(int nSecs)
1306 {
1307 wxMilliSleep(1000*nSecs);
1308 }
1309
1310 // ----------------------------------------------------------------------------
1311 // font encoding <-> Win32 codepage conversion functions
1312 // ----------------------------------------------------------------------------
1313
1314 extern WXDLLIMPEXP_BASE long wxEncodingToCharset(wxFontEncoding encoding)
1315 {
1316 switch ( encoding )
1317 {
1318 // although this function is supposed to return an exact match, do do
1319 // some mappings here for the most common case of "standard" encoding
1320 case wxFONTENCODING_SYSTEM:
1321 return DEFAULT_CHARSET;
1322
1323 case wxFONTENCODING_ISO8859_1:
1324 case wxFONTENCODING_ISO8859_15:
1325 case wxFONTENCODING_CP1252:
1326 return ANSI_CHARSET;
1327
1328 #if !defined(__WXMICROWIN__)
1329 // The following four fonts are multi-byte charsets
1330 case wxFONTENCODING_CP932:
1331 return SHIFTJIS_CHARSET;
1332
1333 case wxFONTENCODING_CP936:
1334 return GB2312_CHARSET;
1335
1336 #ifndef __WXWINCE__
1337 case wxFONTENCODING_CP949:
1338 return HANGUL_CHARSET;
1339 #endif
1340
1341 case wxFONTENCODING_CP950:
1342 return CHINESEBIG5_CHARSET;
1343
1344 // The rest are single byte encodings
1345 case wxFONTENCODING_CP1250:
1346 return EASTEUROPE_CHARSET;
1347
1348 case wxFONTENCODING_CP1251:
1349 return RUSSIAN_CHARSET;
1350
1351 case wxFONTENCODING_CP1253:
1352 return GREEK_CHARSET;
1353
1354 case wxFONTENCODING_CP1254:
1355 return TURKISH_CHARSET;
1356
1357 case wxFONTENCODING_CP1255:
1358 return HEBREW_CHARSET;
1359
1360 case wxFONTENCODING_CP1256:
1361 return ARABIC_CHARSET;
1362
1363 case wxFONTENCODING_CP1257:
1364 return BALTIC_CHARSET;
1365
1366 case wxFONTENCODING_CP874:
1367 return THAI_CHARSET;
1368 #endif // !__WXMICROWIN__
1369
1370 case wxFONTENCODING_CP437:
1371 return OEM_CHARSET;
1372
1373 default:
1374 // no way to translate this encoding into a Windows charset
1375 return -1;
1376 }
1377 }
1378
1379 // we have 2 versions of wxCharsetToCodepage(): the old one which directly
1380 // looks up the vlaues in the registry and the new one which is more
1381 // politically correct and has more chances to work on other Windows versions
1382 // as well but the old version is still needed for !wxUSE_FONTMAP case
1383 #if wxUSE_FONTMAP
1384
1385 #include "wx/fontmap.h"
1386
1387 extern WXDLLIMPEXP_BASE long wxEncodingToCodepage(wxFontEncoding encoding)
1388 {
1389 // There don't seem to be symbolic names for
1390 // these under Windows so I just copied the
1391 // values from MSDN.
1392
1393 unsigned int ret;
1394
1395 switch (encoding)
1396 {
1397 case wxFONTENCODING_ISO8859_1: ret = 28591; break;
1398 case wxFONTENCODING_ISO8859_2: ret = 28592; break;
1399 case wxFONTENCODING_ISO8859_3: ret = 28593; break;
1400 case wxFONTENCODING_ISO8859_4: ret = 28594; break;
1401 case wxFONTENCODING_ISO8859_5: ret = 28595; break;
1402 case wxFONTENCODING_ISO8859_6: ret = 28596; break;
1403 case wxFONTENCODING_ISO8859_7: ret = 28597; break;
1404 case wxFONTENCODING_ISO8859_8: ret = 28598; break;
1405 case wxFONTENCODING_ISO8859_9: ret = 28599; break;
1406 case wxFONTENCODING_ISO8859_10: ret = 28600; break;
1407 case wxFONTENCODING_ISO8859_11: ret = 874; break;
1408 // case wxFONTENCODING_ISO8859_12, // doesn't exist currently, but put it
1409 case wxFONTENCODING_ISO8859_13: ret = 28603; break;
1410 // case wxFONTENCODING_ISO8859_14: ret = 28604; break; // no correspondence on Windows
1411 case wxFONTENCODING_ISO8859_15: ret = 28605; break;
1412 case wxFONTENCODING_KOI8: ret = 20866; break;
1413 case wxFONTENCODING_KOI8_U: ret = 21866; break;
1414 case wxFONTENCODING_CP437: ret = 437; break;
1415 case wxFONTENCODING_CP850: ret = 850; break;
1416 case wxFONTENCODING_CP852: ret = 852; break;
1417 case wxFONTENCODING_CP855: ret = 855; break;
1418 case wxFONTENCODING_CP866: ret = 866; break;
1419 case wxFONTENCODING_CP874: ret = 874; break;
1420 case wxFONTENCODING_CP932: ret = 932; break;
1421 case wxFONTENCODING_CP936: ret = 936; break;
1422 case wxFONTENCODING_CP949: ret = 949; break;
1423 case wxFONTENCODING_CP950: ret = 950; break;
1424 case wxFONTENCODING_CP1250: ret = 1250; break;
1425 case wxFONTENCODING_CP1251: ret = 1251; break;
1426 case wxFONTENCODING_CP1252: ret = 1252; break;
1427 case wxFONTENCODING_CP1253: ret = 1253; break;
1428 case wxFONTENCODING_CP1254: ret = 1254; break;
1429 case wxFONTENCODING_CP1255: ret = 1255; break;
1430 case wxFONTENCODING_CP1256: ret = 1256; break;
1431 case wxFONTENCODING_CP1257: ret = 1257; break;
1432 case wxFONTENCODING_EUC_JP: ret = 20932; break;
1433 case wxFONTENCODING_MACROMAN: ret = 10000; break;
1434 case wxFONTENCODING_MACJAPANESE: ret = 10001; break;
1435 case wxFONTENCODING_MACCHINESETRAD: ret = 10002; break;
1436 case wxFONTENCODING_MACKOREAN: ret = 10003; break;
1437 case wxFONTENCODING_MACARABIC: ret = 10004; break;
1438 case wxFONTENCODING_MACHEBREW: ret = 10005; break;
1439 case wxFONTENCODING_MACGREEK: ret = 10006; break;
1440 case wxFONTENCODING_MACCYRILLIC: ret = 10007; break;
1441 case wxFONTENCODING_MACTHAI: ret = 10021; break;
1442 case wxFONTENCODING_MACCHINESESIMP: ret = 10008; break;
1443 case wxFONTENCODING_MACCENTRALEUR: ret = 10029; break;
1444 case wxFONTENCODING_MACCROATIAN: ret = 10082; break;
1445 case wxFONTENCODING_MACICELANDIC: ret = 10079; break;
1446 case wxFONTENCODING_MACROMANIAN: ret = 10009; break;
1447 case wxFONTENCODING_UTF7: ret = 65000; break;
1448 case wxFONTENCODING_UTF8: ret = 65001; break;
1449 default: return -1;
1450 }
1451
1452 if (::IsValidCodePage(ret) == 0)
1453 return -1;
1454
1455 CPINFO info;
1456 if (::GetCPInfo(ret, &info) == 0)
1457 return -1;
1458
1459 return (long) ret;
1460 }
1461
1462 extern long wxCharsetToCodepage(const wxChar *name)
1463 {
1464 // first get the font encoding for this charset
1465 if ( !name )
1466 return -1;
1467
1468 wxFontEncoding enc = wxFontMapperBase::Get()->CharsetToEncoding(name, false);
1469 if ( enc == wxFONTENCODING_SYSTEM )
1470 return -1;
1471
1472 // the use the helper function
1473 return wxEncodingToCodepage(enc);
1474 }
1475
1476 #else // !wxUSE_FONTMAP
1477
1478 #include "wx/msw/registry.h"
1479
1480 // this should work if Internet Exploiter is installed
1481 extern long wxCharsetToCodepage(const wxChar *name)
1482 {
1483 if (!name)
1484 return GetACP();
1485
1486 long CP = -1;
1487
1488 wxString path(wxT("MIME\\Database\\Charset\\"));
1489 wxString cn(name);
1490
1491 // follow the alias loop
1492 for ( ;; )
1493 {
1494 wxRegKey key(wxRegKey::HKCR, path + cn);
1495
1496 if (!key.Exists())
1497 break;
1498
1499 // two cases: either there's an AliasForCharset string,
1500 // or there are Codepage and InternetEncoding dwords.
1501 // The InternetEncoding gives us the actual encoding,
1502 // the Codepage just says which Windows character set to
1503 // use when displaying the data.
1504 if (key.HasValue(wxT("InternetEncoding")) &&
1505 key.QueryValue(wxT("InternetEncoding"), &CP))
1506 break;
1507
1508 // no encoding, see if it's an alias
1509 if (!key.HasValue(wxT("AliasForCharset")) ||
1510 !key.QueryValue(wxT("AliasForCharset"), cn))
1511 break;
1512 }
1513
1514 return CP;
1515 }
1516
1517 #endif // wxUSE_FONTMAP/!wxUSE_FONTMAP
1518
1519 /*
1520 Creates a hidden window with supplied window proc registering the class for
1521 it if necesssary (i.e. the first time only). Caller is responsible for
1522 destroying the window and unregistering the class (note that this must be
1523 done because wxWidgets may be used as a DLL and so may be loaded/unloaded
1524 multiple times into/from the same process so we cna't rely on automatic
1525 Windows class unregistration).
1526
1527 pclassname is a pointer to a caller stored classname, which must initially be
1528 NULL. classname is the desired wndclass classname. If function successfully
1529 registers the class, pclassname will be set to classname.
1530 */
1531 extern "C" WXDLLIMPEXP_BASE HWND
1532 wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc)
1533 {
1534 wxCHECK_MSG( classname && pclassname && wndproc, NULL,
1535 _T("NULL parameter in wxCreateHiddenWindow") );
1536
1537 // register the class fi we need to first
1538 if ( *pclassname == NULL )
1539 {
1540 WNDCLASS wndclass;
1541 wxZeroMemory(wndclass);
1542
1543 wndclass.lpfnWndProc = wndproc;
1544 wndclass.hInstance = wxGetInstance();
1545 wndclass.lpszClassName = classname;
1546
1547 if ( !::RegisterClass(&wndclass) )
1548 {
1549 wxLogLastError(wxT("RegisterClass() in wxCreateHiddenWindow"));
1550
1551 return NULL;
1552 }
1553
1554 *pclassname = classname;
1555 }
1556
1557 // next create the window
1558 HWND hwnd = ::CreateWindow
1559 (
1560 *pclassname,
1561 NULL,
1562 0, 0, 0, 0,
1563 0,
1564 (HWND) NULL,
1565 (HMENU)NULL,
1566 wxGetInstance(),
1567 (LPVOID) NULL
1568 );
1569
1570 if ( !hwnd )
1571 {
1572 wxLogLastError(wxT("CreateWindow() in wxCreateHiddenWindow"));
1573 }
1574
1575 return hwnd;
1576 }

  ViewVC Help
Powered by ViewVC 1.1.22