utils.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,558 行 · 第 1/4 页
CPP
1,558 行
/////////////////////////////////////////////////////////////////////////////
// Name: msw/utils.cpp
// Purpose: Various utilities
// Author: Julian Smart
// Modified by:
// Created: 04/01/98
// RCS-ID: $Id: utils.cpp,v 1.181.2.3 2005/11/23 12:49:36 ABX Exp $
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/utils.h"
#include "wx/app.h"
#include "wx/intl.h"
#include "wx/log.h"
#endif //WX_PRECOMP
#include "wx/msw/registry.h"
#include "wx/apptrait.h"
#include "wx/dynlib.h"
#include "wx/dynload.h"
#include "wx/scopeguard.h"
#include "wx/confbase.h" // for wxExpandEnvVars()
#include "wx/msw/private.h" // includes <windows.h>
#include "wx/msw/missing.h" // CHARSET_HANGUL
#if defined(__CYGWIN__)
//CYGWIN gives annoying warning about runtime stuff if we don't do this
# define USE_SYS_TYPES_FD_SET
# include <sys/types.h>
#endif
// Doesn't work with Cygwin at present
#if wxUSE_SOCKETS && (defined(__GNUWIN32_OLD__) || defined(__WXWINCE__) || defined(__CYGWIN32__))
// apparently we need to include winsock.h to get WSADATA and other stuff
// used in wxGetFullHostName() with the old mingw32 versions
#include <winsock.h>
#endif
#include "wx/timer.h"
#if !defined(__GNUWIN32__) && !defined(__SALFORDC__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
#include <direct.h>
#ifndef __MWERKS__
#include <dos.h>
#endif
#endif //GNUWIN32
#if defined(__CYGWIN__)
#include <sys/unistd.h>
#include <sys/stat.h>
#include <sys/cygwin.h> // for cygwin_conv_to_full_win32_path()
#endif //GNUWIN32
#ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
// this (3.1 I believe) and how to test for it.
// If this works for Borland 4.0 as well, then no worries.
#include <dir.h>
#endif
// VZ: there is some code using NetXXX() functions to get the full user name:
// I don't think it's a good idea because they don't work under Win95 and
// seem to return the same as wxGetUserId() under NT. If you really want
// to use them, just #define USE_NET_API
#undef USE_NET_API
#ifdef USE_NET_API
#include <lm.h>
#endif // USE_NET_API
#if defined(__WIN32__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
#ifndef __UNIX__
#include <io.h>
#endif
#ifndef __GNUWIN32__
#include <shellapi.h>
#endif
#endif
#ifndef __WATCOMC__
#if !(defined(_MSC_VER) && (_MSC_VER > 800))
#include <errno.h>
#endif
#endif
// For wxKillAllChildren
#include <tlhelp32.h>
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// In the WIN.INI file
static const wxChar WX_SECTION[] = wxT("wxWindows");
static const wxChar eUSERNAME[] = wxT("UserName");
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// get host name and related
// ----------------------------------------------------------------------------
// Get hostname only (without domain name)
bool wxGetHostName(wxChar *WXUNUSED_IN_WINCE(buf),
int WXUNUSED_IN_WINCE(maxSize))
{
#if defined(__WXWINCE__)
// TODO-CE
return false;
#elif defined(__WIN32__) && !defined(__WXMICROWIN__)
DWORD nSize = maxSize;
if ( !::GetComputerName(buf, &nSize) )
{
wxLogLastError(wxT("GetComputerName"));
return false;
}
return true;
#else
wxChar *sysname;
const wxChar *default_host = wxT("noname");
if ((sysname = wxGetenv(wxT("SYSTEM_NAME"))) == NULL) {
GetProfileString(WX_SECTION, eHOSTNAME, default_host, buf, maxSize - 1);
} else
wxStrncpy(buf, sysname, maxSize - 1);
buf[maxSize] = wxT('\0');
return *buf ? true : false;
#endif
}
// get full hostname (with domain name if possible)
bool wxGetFullHostName(wxChar *buf, int maxSize)
{
#if !defined( __WXMICROWIN__) && wxUSE_DYNAMIC_LOADER && wxUSE_SOCKETS
// TODO should use GetComputerNameEx() when available
// we don't want to always link with Winsock DLL as we might not use it at
// all, so load it dynamically here if needed (and don't complain if it is
// missing, we handle this)
wxLogNull noLog;
wxDynamicLibrary dllWinsock(_T("ws2_32.dll"), wxDL_VERBATIM);
if ( dllWinsock.IsLoaded() )
{
typedef int (PASCAL *WSAStartup_t)(WORD, WSADATA *);
typedef int (PASCAL *gethostname_t)(char *, int);
typedef hostent* (PASCAL *gethostbyname_t)(const char *);
typedef hostent* (PASCAL *gethostbyaddr_t)(const char *, int , int);
typedef int (PASCAL *WSACleanup_t)(void);
#define LOAD_WINSOCK_FUNC(func) \
func ## _t \
pfn ## func = (func ## _t)dllWinsock.GetSymbol(_T(#func))
LOAD_WINSOCK_FUNC(WSAStartup);
WSADATA wsa;
if ( pfnWSAStartup && pfnWSAStartup(MAKEWORD(1, 1), &wsa) == 0 )
{
LOAD_WINSOCK_FUNC(gethostname);
wxString host;
if ( pfngethostname )
{
char bufA[256];
if ( pfngethostname(bufA, WXSIZEOF(bufA)) == 0 )
{
// gethostname() won't usually include the DNS domain name,
// for this we need to work a bit more
if ( !strchr(bufA, '.') )
{
LOAD_WINSOCK_FUNC(gethostbyname);
struct hostent *pHostEnt = pfngethostbyname
? pfngethostbyname(bufA)
: NULL;
if ( pHostEnt )
{
// Windows will use DNS internally now
LOAD_WINSOCK_FUNC(gethostbyaddr);
pHostEnt = pfngethostbyaddr
? pfngethostbyaddr(pHostEnt->h_addr,
4, AF_INET)
: NULL;
}
if ( pHostEnt )
{
host = wxString::FromAscii(pHostEnt->h_name);
}
}
}
}
LOAD_WINSOCK_FUNC(WSACleanup);
if ( pfnWSACleanup )
pfnWSACleanup();
if ( !host.empty() )
{
wxStrncpy(buf, host, maxSize);
return true;
}
}
}
#endif // !__WXMICROWIN__
return wxGetHostName(buf, maxSize);
}
// Get user ID e.g. jacs
bool wxGetUserId(wxChar *WXUNUSED_IN_WINCE(buf),
int WXUNUSED_IN_WINCE(maxSize))
{
#if defined(__WXWINCE__)
// TODO-CE
return false;
#elif defined(__WIN32__) && !defined(__WXMICROWIN__)
DWORD nSize = maxSize;
if ( ::GetUserName(buf, &nSize) == 0 )
{
// actually, it does happen on Win9x if the user didn't log on
DWORD res = ::GetEnvironmentVariable(wxT("username"), buf, maxSize);
if ( res == 0 )
{
// not found
return false;
}
}
return true;
#else // __WXMICROWIN__
wxChar *user;
const wxChar *default_id = wxT("anonymous");
// Can't assume we have NIS (PC-NFS) or some other ID daemon
// So we ...
if ( (user = wxGetenv(wxT("USER"))) == NULL &&
(user = wxGetenv(wxT("LOGNAME"))) == NULL )
{
// Use wxWidgets configuration data (comming soon)
GetProfileString(WX_SECTION, eUSERID, default_id, buf, maxSize - 1);
}
else
{
wxStrncpy(buf, user, maxSize - 1);
}
return *buf ? true : false;
#endif
}
// Get user name e.g. Julian Smart
bool wxGetUserName(wxChar *buf, int maxSize)
{
wxCHECK_MSG( buf && ( maxSize > 0 ), false,
_T("empty buffer in wxGetUserName") );
#if defined(__WXWINCE__)
wxLogNull noLog;
wxRegKey key(wxRegKey::HKCU, wxT("ControlPanel\\Owner"));
if(!key.Open(wxRegKey::Read))
return false;
wxString name;
if(!key.QueryValue(wxT("Owner"),name))
return false;
wxStrncpy(buf, name.c_str(), maxSize-1);
buf[maxSize-1] = _T('\0');
return true;
#elif defined(USE_NET_API)
CHAR szUserName[256];
if ( !wxGetUserId(szUserName, WXSIZEOF(szUserName)) )
return false;
// TODO how to get the domain name?
CHAR *szDomain = "";
// the code is based on the MSDN example (also see KB article Q119670)
WCHAR wszUserName[256]; // Unicode user name
WCHAR wszDomain[256];
LPBYTE ComputerName;
USER_INFO_2 *ui2; // User structure
// Convert ANSI user name and domain to Unicode
MultiByteToWideChar( CP_ACP, 0, szUserName, strlen(szUserName)+1,
wszUserName, WXSIZEOF(wszUserName) );
MultiByteToWideChar( CP_ACP, 0, szDomain, strlen(szDomain)+1,
wszDomain, WXSIZEOF(wszDomain) );
// Get the computer name of a DC for the domain.
if ( NetGetDCName( NULL, wszDomain, &ComputerName ) != NERR_Success )
{
wxLogError(wxT("Can not find domain controller"));
goto error;
}
// Look up the user on the DC
NET_API_STATUS status = NetUserGetInfo( (LPWSTR)ComputerName,
(LPWSTR)&wszUserName,
2, // level - we want USER_INFO_2
(LPBYTE *) &ui2 );
switch ( status )
{
case NERR_Success:
// ok
break;
case NERR_InvalidComputer:
wxLogError(wxT("Invalid domain controller name."));
goto error;
case NERR_UserNotFound:
wxLogError(wxT("Invalid user name '%s'."), szUserName);
goto error;
default:
wxLogSysError(wxT("Can't get information about user"));
goto error;
}
// Convert the Unicode full name to ANSI
WideCharToMultiByte( CP_ACP, 0, ui2->usri2_full_name, -1,
buf, maxSize, NULL, NULL );
return true;
error:
wxLogError(wxT("Couldn't look up full user name."));
return false;
#else // !USE_NET_API
// Could use NIS, MS-Mail or other site specific programs
// Use wxWidgets configuration data
bool ok = GetProfileString(WX_SECTION, eUSERNAME, wxEmptyString, buf, maxSize - 1) != 0;
if ( !ok )
{
ok = wxGetUserId(buf, maxSize);
}
if ( !ok )
{
wxStrncpy(buf, wxT("Unknown User"), maxSize);
}
return true;
#endif // Win32/16
}
const wxChar* wxGetHomeDir(wxString *pstr)
{
wxString& strDir = *pstr;
// first branch is for Cygwin
#if defined(__UNIX__)
const wxChar *szHome = wxGetenv("HOME");
if ( szHome == NULL ) {
// we're homeless...
wxLogWarning(_("can't find user's HOME, using current directory."));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?