X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/695578271d97f6c7021c8769b59e966e2c10d715..10a59880771fae005b31e003916a028267b54427:/src/msw/utils.cpp?ds=sidebyside diff --git a/src/msw/utils.cpp b/src/msw/utils.cpp index 770ea11fe2..9d83179e0a 100644 --- a/src/msw/utils.cpp +++ b/src/msw/utils.cpp @@ -32,10 +32,15 @@ #endif //WX_PRECOMP #include "wx/apptrait.h" +#include "wx/dynload.h" + +#include "wx/confbase.h" // for wxExpandEnvVars() #include "wx/msw/private.h" // includes +#include "wx/msw/missing.h" // CHARSET_HANGUL -#ifdef __GNUWIN32_OLD__ +#if 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 @@ -43,7 +48,7 @@ #include "wx/timer.h" -#if !defined(__GNUWIN32__) && !defined(__SALFORDC__) && !defined(__WXMICROWIN__) +#if !defined(__GNUWIN32__) && !defined(__SALFORDC__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__) #include #ifndef __MWERKS__ @@ -73,7 +78,7 @@ #include #endif // USE_NET_API -#if defined(__WIN32__) && !defined(__WXMICROWIN__) +#if defined(__WIN32__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__) #ifndef __UNIX__ #include #endif @@ -89,6 +94,11 @@ #endif #endif +// 260 was taken from windef.h +#ifndef MAX_PATH + #define MAX_PATH 260 +#endif + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -97,12 +107,6 @@ static const wxChar WX_SECTION[] = wxT("wxWindows"); static const wxChar eUSERNAME[] = wxT("UserName"); -// these are only used under Win16 -#if !defined(__WIN32__) && !defined(__WXMICROWIN__) -static const wxChar eHOSTNAME[] = wxT("HostName"); -static const wxChar eUSERID[] = wxT("UserId"); -#endif // !Win32 - // ============================================================================ // implementation // ============================================================================ @@ -114,13 +118,15 @@ static const wxChar eUSERID[] = wxT("UserId"); // Get hostname only (without domain name) bool wxGetHostName(wxChar *buf, int maxSize) { -#if defined(__WIN32__) && !defined(__WXMICROWIN__) +#if defined(__WXWINCE__) + return false; +#elif defined(__WIN32__) && !defined(__WXMICROWIN__) DWORD nSize = maxSize; if ( !::GetComputerName(buf, &nSize) ) { wxLogLastError(wxT("GetComputerName")); - return FALSE; + return false; } return TRUE; @@ -140,53 +146,83 @@ bool wxGetHostName(wxChar *buf, int maxSize) // get full hostname (with domain name if possible) bool wxGetFullHostName(wxChar *buf, int maxSize) { -#if defined(__WIN32__) && !defined(__WXMICROWIN__) && ! (defined(__GNUWIN32__) && !defined(__MINGW32__)) +#if !defined( __WXMICROWIN__) && wxUSE_DYNAMIC_LOADER // TODO should use GetComputerNameEx() when available - // the idea is that if someone had set wxUSE_SOCKETS to 0 the code - // shouldn't use winsock.dll (a.k.a. ws2_32.dll) at all so only use this - // code if we link with it anyhow -#if wxUSE_SOCKETS + // 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; - WSADATA wsa; - if ( WSAStartup(MAKEWORD(1, 1), &wsa) == 0 ) + wxDynamicLibrary dllWinsock(_T("ws2_32.dll"), wxDL_VERBATIM); + if ( dllWinsock.IsLoaded() ) { - wxString host; - char bufA[256]; - if ( gethostname(bufA, WXSIZEOF(bufA)) == 0 ) + 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 ) { - // gethostname() won't usually include the DNS domain name, for - // this we need to work a bit more - if ( !strchr(bufA, '.') ) - { - struct hostent *pHostEnt = gethostbyname(bufA); + LOAD_WINSOCK_FUNC(gethostname); - if ( pHostEnt ) + wxString host; + if ( pfngethostname ) + { + char bufA[256]; + if ( pfngethostname(bufA, WXSIZEOF(bufA)) == 0 ) { - // Windows will use DNS internally now - pHostEnt = gethostbyaddr(pHostEnt->h_addr, 4, AF_INET); - } + // 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); - if ( pHostEnt ) - { - host = wxString::FromAscii(pHostEnt->h_name); + 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); + } + } } } - } - WSACleanup(); + LOAD_WINSOCK_FUNC(WSACleanup); + if ( pfnWSACleanup ) + pfnWSACleanup(); - if ( !host.empty() ) - { - wxStrncpy(buf, host, maxSize); - return TRUE; + if ( !host.empty() ) + { + wxStrncpy(buf, host, maxSize); + + return TRUE; + } } } - -#endif // wxUSE_SOCKETS - -#endif // Win32 +#endif // !__WXMICROWIN__ return wxGetHostName(buf, maxSize); } @@ -194,7 +230,9 @@ bool wxGetFullHostName(wxChar *buf, int maxSize) // Get user ID e.g. jacs bool wxGetUserId(wxChar *buf, int maxSize) { -#if defined(__WIN32__) && !defined(__win32s__) && !defined(__WXMICROWIN__) +#if defined(__WXWINCE__) + return false; +#elif defined(__WIN32__) && !defined(__WXMICROWIN__) DWORD nSize = maxSize; if ( ::GetUserName(buf, &nSize) == 0 ) { @@ -208,7 +246,7 @@ bool wxGetUserId(wxChar *buf, int maxSize) } return TRUE; -#else // Win16 or Win32s +#else // __WXMICROWIN__ wxChar *user; const wxChar *default_id = wxT("anonymous"); @@ -217,7 +255,7 @@ bool wxGetUserId(wxChar *buf, int maxSize) if ( (user = wxGetenv(wxT("USER"))) == NULL && (user = wxGetenv(wxT("LOGNAME"))) == NULL ) { - // Use wxWindows configuration data (comming soon) + // Use wxWidgets configuration data (comming soon) GetProfileString(WX_SECTION, eUSERID, default_id, buf, maxSize - 1); } else @@ -232,108 +270,98 @@ bool wxGetUserId(wxChar *buf, int maxSize) // Get user name e.g. Julian Smart bool wxGetUserName(wxChar *buf, int maxSize) { -#if wxUSE_PENWINDOWS && !defined(__WATCOMC__) && !defined(__GNUWIN32__) - extern HANDLE g_hPenWin; // PenWindows Running? - if (g_hPenWin) - { - // PenWindows Does have a user concept! - // Get the current owner of the recognizer - GetPrivateProfileString("Current", "User", default_name, wxBuffer, maxSize - 1, "PENWIN.INI"); - strncpy(buf, wxBuffer, maxSize - 1); - } - else -#endif +#if defined(__WXWINCE__) + return false; +#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 ) { -#ifdef 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; + wxLogError(wxT("Can not find domain controller")); - USER_INFO_2 *ui2; // User structure + goto error; + } - // 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) ); + // 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; - // Get the computer name of a DC for the domain. - if ( NetGetDCName( NULL, wszDomain, &ComputerName ) != NERR_Success ) - { - wxLogError(wxT("Can not find domain controller")); + case NERR_InvalidComputer: + wxLogError(wxT("Invalid domain controller name.")); 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.")); + case NERR_UserNotFound: + wxLogError(wxT("Invalid user name '%s'."), szUserName); - goto error; - - case NERR_UserNotFound: - wxLogError(wxT("Invalid user name '%s'."), szUserName); - - goto error; + goto error; - default: - wxLogSysError(wxT("Can't get information about user")); + default: + wxLogSysError(wxT("Can't get information about user")); - goto error; - } + goto error; + } - // Convert the Unicode full name to ANSI - WideCharToMultiByte( CP_ACP, 0, ui2->usri2_full_name, -1, - buf, maxSize, NULL, NULL ); + // Convert the Unicode full name to ANSI + WideCharToMultiByte( CP_ACP, 0, ui2->usri2_full_name, -1, + buf, maxSize, NULL, NULL ); - return TRUE; + return TRUE; error: - wxLogError(wxT("Couldn't look up full user name.")); + wxLogError(wxT("Couldn't look up full user name.")); - return FALSE; + return FALSE; #else // !USE_NET_API - // Could use NIS, MS-Mail or other site specific programs - // Use wxWindows configuration data - bool ok = GetProfileString(WX_SECTION, eUSERNAME, wxT(""), buf, maxSize - 1) != 0; - if ( !ok ) - { - ok = wxGetUserId(buf, maxSize); - } + // 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); - } -#endif // Win32/16 + if ( !ok ) + { + wxStrncpy(buf, wxT("Unknown User"), maxSize); } +#endif // Win32/16 return TRUE; } const wxChar* wxGetHomeDir(wxString *pstr) { - wxString& strDir = *pstr; + wxString& strDir = *pstr; - #if defined(__UNIX__) + // first branch is for Cygwin +#if defined(__UNIX__) const wxChar *szHome = wxGetenv("HOME"); if ( szHome == NULL ) { // we're homeless... @@ -348,32 +376,33 @@ const wxChar* wxGetHomeDir(wxString *pstr) strDir << wxT('/'); #ifdef __CYGWIN__ - // Cygwin returns unix type path but that does not work well - static wxChar windowsPath[MAX_PATH]; - cygwin_conv_to_full_win32_path(strDir, windowsPath); - strDir = windowsPath; + // Cygwin returns unix type path but that does not work well + static wxChar windowsPath[MAX_PATH]; + cygwin_conv_to_full_win32_path(strDir, windowsPath); + strDir = windowsPath; #endif - #else // Windows - #ifdef __WIN32__ - strDir.clear(); +#elif defined(__WXWINCE__) + // Nothing +#else + strDir.clear(); - // If we have a valid HOME directory, as is used on many machines that - // have unix utilities on them, we should use that. - const wxChar *szHome = wxGetenv(wxT("HOME")); + // If we have a valid HOME directory, as is used on many machines that + // have unix utilities on them, we should use that. + const wxChar *szHome = wxGetenv(wxT("HOME")); - if ( szHome != NULL ) - { + if ( szHome != NULL ) + { strDir = szHome; - } - else // no HOME, try HOMEDRIVE/PATH - { - szHome = wxGetenv(wxT("HOMEDRIVE")); - if ( szHome != NULL ) + } + else // no HOME, try HOMEDRIVE/PATH + { + szHome = wxGetenv(wxT("HOMEDRIVE")); + if ( szHome != NULL ) strDir << szHome; - szHome = wxGetenv(wxT("HOMEPATH")); + szHome = wxGetenv(wxT("HOMEPATH")); - if ( szHome != NULL ) - { + if ( szHome != NULL ) + { strDir << szHome; // the idea is that under NT these variables have default values @@ -383,45 +412,38 @@ const wxChar* wxGetHomeDir(wxString *pstr) // to set HOMEPATH to something other than "\\", we suppose that he // knows what he is doing and use the supplied value. if ( wxStrcmp(szHome, wxT("\\")) == 0 ) - strDir.clear(); - } - } + strDir.clear(); + } + } - if ( strDir.empty() ) - { - // If we have a valid USERPROFILE directory, as is the case in - // Windows NT, 2000 and XP, we should use that as our home directory. - szHome = wxGetenv(wxT("USERPROFILE")); + if ( strDir.empty() ) + { + // If we have a valid USERPROFILE directory, as is the case in + // Windows NT, 2000 and XP, we should use that as our home directory. + szHome = wxGetenv(wxT("USERPROFILE")); - if ( szHome != NULL ) + if ( szHome != NULL ) strDir = szHome; - } - - if ( !strDir.empty() ) - { - return strDir.c_str(); - } - //else: fall back to the prograrm directory - #else // Win16 - // Win16 has no idea about home, so use the executable directory instead - #endif // WIN16/32 - - // 260 was taken from windef.h - #ifndef MAX_PATH - #define MAX_PATH 260 - #endif - - wxString strPath; - ::GetModuleFileName(::GetModuleHandle(NULL), - strPath.GetWriteBuf(MAX_PATH), MAX_PATH); - strPath.UngetWriteBuf(); + } - // extract the dir name - wxSplitPath(strPath, &strDir, NULL, NULL); + if ( !strDir.empty() ) + { + // sometimes the value of HOME may be "%USERPROFILE%", so reexpand the + // value once again, it shouldn't hurt anyhow + strDir = wxExpandEnvVars(strDir); + } + else // fall back to the program directory + { + wxString strPath; + ::GetModuleFileName(::GetModuleHandle(NULL), + wxStringBuffer(strPath, MAX_PATH), MAX_PATH); - #endif // UNIX/Win + // extract the dir name + wxSplitPath(strPath, &strDir, NULL, NULL); + } +#endif // UNIX/Win - return strDir.c_str(); + return strDir.c_str(); } wxChar *wxGetUserHome(const wxString& WXUNUSED(user)) @@ -441,29 +463,16 @@ bool wxDirExists(const wxString& dir) #elif defined(__WIN32__) DWORD attribs = GetFileAttributes(dir); return ((attribs != (DWORD)-1) && (attribs & FILE_ATTRIBUTE_DIRECTORY)); -#else // Win16 - #ifdef __BORLANDC__ - struct ffblk fileInfo; - #else - struct find_t fileInfo; - #endif - // In Borland findfirst has a different argument - // ordering from _dos_findfirst. But _dos_findfirst - // _should_ be ok in both MS and Borland... why not? - #ifdef __BORLANDC__ - return (findfirst(dir, &fileInfo, _A_SUBDIR) == 0 && - (fileInfo.ff_attrib & _A_SUBDIR) != 0); - #else - return (_dos_findfirst(dir, _A_SUBDIR, &fileInfo) == 0) && - ((fileInfo.attrib & _A_SUBDIR) != 0); - #endif -#endif // Win32/16 +#endif // Win32/__WXMICROWIN__ } bool wxGetDiskSpace(const wxString& path, wxLongLong *pTotal, wxLongLong *pFree) { +#ifdef __WXWINCE__ + return false; +#else if ( path.empty() ) - return FALSE; + return false; // old w32api don't have ULARGE_INTEGER #if defined(__WIN32__) && \ @@ -561,6 +570,8 @@ bool wxGetDiskSpace(const wxString& path, wxLongLong *pTotal, wxLongLong *pFree) } return TRUE; +#endif + // __WXWINCE__ } // ---------------------------------------------------------------------------- @@ -569,17 +580,8 @@ bool wxGetDiskSpace(const wxString& path, wxLongLong *pTotal, wxLongLong *pFree) bool wxGetEnv(const wxString& var, wxString *value) { -#ifdef __WIN16__ - const wxChar* ret = wxGetenv(var); - if ( !ret ) - return FALSE; - - if ( value ) - { - *value = ret; - } - - return TRUE; +#ifdef __WXWINCE__ + return FALSE; #else // Win32 // first get the size of the buffer DWORD dwRet = ::GetEnvironmentVariable(var, NULL, 0); @@ -591,19 +593,19 @@ bool wxGetEnv(const wxString& var, wxString *value) if ( value ) { - (void)::GetEnvironmentVariable(var, value->GetWriteBuf(dwRet), dwRet); - value->UngetWriteBuf(); + (void)::GetEnvironmentVariable(var, wxStringBuffer(*value, dwRet), + dwRet); } return TRUE; -#endif // Win16/32 +#endif // WinCE/32 } bool wxSetEnv(const wxString& var, const wxChar *value) { // some compilers have putenv() or _putenv() or _wputenv() but it's better // to always use Win32 function directly instead of dealing with them -#if defined(__WIN32__) +#if defined(__WIN32__) && !defined(__WXWINCE__) if ( !::SetEnvironmentVariable(var, value) ) { wxLogLastError(_T("SetEnvironmentVariable")); @@ -815,11 +817,15 @@ int wxKill(long pid, wxSignal sig, wxKillError *krc) // Execute a program in an Interactive Shell bool wxShell(const wxString& command) { + wxString cmd; + +#ifdef __WXWINCE__ + cmd = command; +#else wxChar *shell = wxGetenv(wxT("COMSPEC")); if ( !shell ) shell = (wxChar*) wxT("\\COMMAND.COM"); - wxString cmd; if ( !command ) { // just the shell @@ -830,6 +836,7 @@ bool wxShell(const wxString& command) // pass the command to execute to the command processor cmd.Printf(wxT("%s /c %s"), shell, command.c_str()); } +#endif return wxExecute(cmd, wxEXEC_SYNC) == 0; } @@ -837,7 +844,9 @@ bool wxShell(const wxString& command) // Shutdown or reboot the PC bool wxShutdown(wxShutdownFlags wFlags) { -#ifdef __WIN32__ +#ifdef __WXWINCE__ + return FALSE; +#elif defined(__WIN32__) bool bOK = TRUE; if ( wxGetOsVersion(NULL, NULL) == wxWINDOWS_NT ) // if is NT or 2K @@ -885,12 +894,10 @@ bool wxShutdown(wxShutdownFlags wFlags) return FALSE; } - bOK = ::ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE | EWX_REBOOT, 0) != 0; + bOK = ::ExitWindowsEx(flags, 0) != 0; } return bOK; -#else // Win16 - return FALSE; #endif // Win32/16 } @@ -913,11 +920,7 @@ long wxGetFreeMemory() unsigned long wxGetProcessId() { -#ifdef __WIN32__ return ::GetCurrentProcessId(); -#else - return 0; -#endif } // Emit a beeeeeep @@ -928,7 +931,6 @@ void wxBell() wxString wxGetOsDescription() { -#ifdef __WIN32__ wxString str; OSVERSIONINFO info; @@ -971,12 +973,9 @@ wxString wxGetOsDescription() } return str; -#else // Win16 - return _("Windows 3.1"); -#endif // Win32/16 } -int wxAppTraits::GetOSVersion(int *verMaj, int *verMin) +wxToolkitInfo& wxAppTraits::GetToolkitInfo() { // cache the version info, it's not going to change // @@ -1011,37 +1010,47 @@ int wxAppTraits::GetOSVersion(int *verMaj, int *verMin) case VER_PLATFORM_WIN32_NT: s_ver = wxWINDOWS_NT; break; +#ifdef __WXWINCE__ + case VER_PLATFORM_WIN32_CE: + s_ver = wxWINDOWS_CE; + break; +#endif } } } - if ( verMaj ) - *verMaj = s_major; - if ( verMin ) - *verMin = s_minor; - - return s_ver; + static wxToolkitInfo info; + info.versionMajor = s_major; + info.versionMinor = s_minor; + info.os = s_ver; + info.name = _T("wxBase"); + return info; } // ---------------------------------------------------------------------------- // sleep functions // ---------------------------------------------------------------------------- -void wxUsleep(unsigned long milliseconds) +void wxMilliSleep(unsigned long milliseconds) { ::Sleep(milliseconds); } +void wxMicroSleep(unsigned long microseconds) +{ + wxMilliSleep(microseconds/1000); +} + void wxSleep(int nSecs) { - wxUsleep(1000*nSecs); + wxMilliSleep(1000*nSecs); } // ---------------------------------------------------------------------------- // font encoding <-> Win32 codepage conversion functions // ---------------------------------------------------------------------------- -extern long wxEncodingToCharset(wxFontEncoding encoding) +extern WXDLLIMPEXP_BASE long wxEncodingToCharset(wxFontEncoding encoding) { switch ( encoding ) { @@ -1097,12 +1106,11 @@ extern long wxEncodingToCharset(wxFontEncoding encoding) case wxFONTENCODING_CP437: return OEM_CHARSET; - default: // fix GCC warning + + default: + // no way to translate this encoding into a Windows charset return -1; } - - // no way to translate this encoding into a Windows charset - return -1; } // we have 2 versions of wxCharsetToCodepage(): the old one which directly @@ -1113,7 +1121,7 @@ extern long wxEncodingToCharset(wxFontEncoding encoding) #include "wx/fontmap.h" -extern long wxEncodingToCodepage(wxFontEncoding encoding) +extern WXDLLIMPEXP_BASE long wxEncodingToCodepage(wxFontEncoding encoding) { // translate encoding into the Windows CHARSET long charset = wxEncodingToCharset(encoding); @@ -1191,3 +1199,62 @@ extern long wxCharsetToCodepage(const wxChar *name) #endif // wxUSE_FONTMAP/!wxUSE_FONTMAP +/* + Creates a hidden window with supplied window proc registering the class for + it if necesssary (i.e. the first time only). Caller is responsible for + destroying the window and unregistering the class (note that this must be + done because wxWidgets may be used as a DLL and so may be loaded/unloaded + multiple times into/from the same process so we cna't rely on automatic + Windows class unregistration). + + pclassname is a pointer to a caller stored classname, which must initially be + NULL. classname is the desired wndclass classname. If function succesfully + registers the class, pclassname will be set to classname. + */ +extern "C" WXDLLIMPEXP_BASE HWND +wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc) +{ + wxCHECK_MSG( classname && pclassname && wndproc, NULL, + _T("NULL parameter in wxCreateHiddenWindow") ); + + // register the class fi we need to first + if ( *pclassname == NULL ) + { + WNDCLASS wndclass; + wxZeroMemory(wndclass); + + wndclass.lpfnWndProc = wndproc; + wndclass.hInstance = wxGetInstance(); + wndclass.lpszClassName = classname; + + if ( !::RegisterClass(&wndclass) ) + { + wxLogLastError(wxT("RegisterClass() in wxCreateHiddenWindow")); + + return NULL; + } + + *pclassname = classname; + } + + // next create the window + HWND hwnd = ::CreateWindow + ( + *pclassname, + NULL, + 0, 0, 0, 0, + 0, + (HWND) NULL, + (HMENU)NULL, + wxGetInstance(), + (LPVOID) NULL + ); + + if ( !hwnd ) + { + wxLogLastError(wxT("CreateWindow() in wxCreateHiddenWindow")); + } + + return hwnd; +} +