]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/utils.cpp
moved common code from ctor and Create() to a separate Init() function
[wxWidgets.git] / src / msw / utils.cpp
index 361bd94e310a7127d395d9aed1efc652781af6dd..6d3ca69dffbac80a3ca2dd12a7fa0b41ca6fda4e 100644 (file)
@@ -6,12 +6,11 @@
 // Created:     04/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart and Markus Holzem
-// Licence:    wxWindows license
+// Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
-#pragma implementation
-#pragma implementation "utils.h"
+// #pragma implementation "utils.h"   // Note: this is done in utilscmn.cpp now.
 #endif
 
 // For compilers that support precompilation, includes "wx.h".
@@ -26,7 +25,7 @@
 #include "wx/utils.h"
 #include "wx/app.h"
 #include "wx/cursor.h"
-#endif
+#endif  //WX_PRECOMP
 
 #include "wx/msw/private.h"
 #include "wx/timer.h"
 #ifndef __GNUWIN32__
 #include <direct.h>
 #include <dos.h>
-#endif
+#endif  //GNUWIN32
 
 #ifdef __GNUWIN32__
 #include <sys/unistd.h>
 #include <sys/stat.h>
-#ifndef __MINGW32__
-#include <std.h>
-#endif
+#endif  //GNUWIN32
 
-#define stricmp strcasecmp
-#endif
+#include "wx/log.h"
 
 #ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
                     // this (3.1 I believe) and how to test for it.
@@ -78,10 +74,6 @@ static const char eHOSTNAME[]  = "HostName";
 static const char eUSERID[]    = "UserId";
 static const char eUSERNAME[]  = "UserName";
 
-#if !USE_SHARED_LIBRARY
-IMPLEMENT_DYNAMIC_CLASS(wxPathList, wxList)
-#endif
-
 // For the following functions we SHOULD fill in support
 // for Windows-NT (which I don't know) as I assume it begin
 // a POSIX Unix (so claims MS) that it has some special
@@ -163,8 +155,8 @@ bool wxGetUserId(char *buf, int maxSize)
 
   // Can't assume we have NIS (PC-NFS) or some other ID daemon
   // So we ...
-  if ( (user = getenv("USER")) == NULL &&
-       (user = getenv("LOGNAME")) == NULL ) {
+  if (  (user = getenv("USER")) == NULL &&
+  (user = getenv("LOGNAME")) == NULL ) {
      // Use wxWindows configuration data (comming soon)
      GetProfileString(WX_SECTION, eUSERID, default_id, buf, maxSize - 1);
   } else
@@ -191,9 +183,9 @@ bool wxGetUserName(char *buf, int maxSize)
     return *buf ? TRUE : FALSE;
 //  }
 #else
-#if !defined(__WATCOMC__) && !defined(__GNUWIN32__) && USE_PENWINDOWS
-  extern HANDLE hPenWin; // PenWindows Running?
-  if (hPenWin)
+#if !defined(__WATCOMC__) && !defined(__GNUWIN32__) && wxUSE_PENWINDOWS
+  extern HANDLE g_hPenWin; // PenWindows Running?
+  if (g_hPenWin)
   {
     // PenWindows Does have a user concept!
     // Get the current owner of the recognizer
@@ -211,97 +203,6 @@ bool wxGetUserName(char *buf, int maxSize)
 #endif
 }
 
-// Execute a command (e.g. another program) in a
-// system-independent manner.
-
-long wxExecute(char **argv, bool sync)
-{
-  if (*argv == NULL)
-    return 0;
-
-  char command[1024];
-  command[0] = '\0';
-
-  int argc;
-  for (argc = 0; argv[argc]; argc++)
-   {
-    if (argc)
-      strcat(command, " ");
-    strcat(command, argv[argc]);
-   }
-
-  return wxExecute((char *)command, sync);
-}
-
-long wxExecute(const wxString& command, bool sync)
-{
-  if (command == "")
-    return 0;
-
-#ifdef __WIN32__
-  char * cl;
-  char * argp;
-  int clen;
-  HINSTANCE result;
-  DWORD dresult;
-
-  // copy the command line
-  clen = command.Length();
-  if (!clen) return -1;
-  cl = (char *) calloc( 1, 256);
-  if (!cl) return -1;
-  strcpy( cl, WXSTRINGCAST command);
-
-  // isolate command and arguments
-  argp = strchr( cl, ' ');
-  if (argp)
-    *argp++ = '\0';
-
-  // execute the command
-#ifdef __GNUWIN32__
-  result = ShellExecute( (HWND) (wxTheApp->GetTopWindow() ? (HWND) wxTheApp->GetTopWindow()->GetHWND() : NULL),
-     (const wchar_t) "open", (const wchar_t) cl, (const wchar_t) argp, (const wchar_t) NULL, SW_SHOWNORMAL);
-#else
-  result = ShellExecute( (HWND) (wxTheApp->GetTopWindow() ? wxTheApp->GetTopWindow()->GetHWND() : NULL),
-     "open", cl, argp, NULL, SW_SHOWNORMAL);
-#endif
-
-  if (((long)result) <= 32) {
-   free(cl);
-   return 0;
-  }
-  
-  if (!sync)
-  {
-    free(cl);
-    return dresult;
-  }
-
-  // waiting until command executed
-  do {
-    wxYield();
-    dresult = GetModuleFileName( result, cl, 256);
-  } while( dresult);
-  
-  /* long lastError = GetLastError(); */
-
-  free(cl);
-  return 0;
-#else
-  long instanceID = WinExec((LPCSTR) WXSTRINGCAST command, SW_SHOW);
-  if (instanceID < 32) return(0);
-
-  if (sync) {
-    int running;
-    do {
-      wxYield();
-      running = GetModuleUsage((HANDLE)instanceID);
-    } while (running);
-  }
-  return(instanceID);
-#endif
-}
-
 int wxKill(long pid, int sig)
 {
   return 0;
@@ -417,76 +318,62 @@ void wxFatalError(const wxString& msg, const wxString& title)
 void wxBell(void)
 {
 #ifdef __WIN32__
-  Beep(1000,1000) ;    // 1kHz during 1 sec.
+  Beep(1000,1000) ; // 1kHz during 1 sec.
 #else
   MessageBeep(-1) ;
 #endif
 }
 
+// Chris Breeze 27/5/98: revised WIN32 code to
+// detect WindowsNT correctly
 int wxGetOsVersion(int *majorVsn, int *minorVsn)
 {
   extern char *wxOsVersion;
-  if (majorVsn)
-    *majorVsn = 0;
-  if (minorVsn)
-    *minorVsn = 0;
-    
-  int retValue ;
-#ifndef __WIN32__
-#ifdef __WINDOWS_386__
-  retValue = wxWIN386;
-#else
-
-#if !defined(__WATCOMC__) && !defined(__GNUWIN32__) && USE_PENWINDOWS
-  extern HANDLE hPenWin;
-  retValue = hPenWin ? wxPENWINDOWS : wxWINDOWS ;
-#endif
-
-#endif
-#else
-  DWORD Version = GetVersion() ;
-  WORD  lowWord  = LOWORD(Version) ;
-  
-  if (wxOsVersion)
+  if (majorVsn) *majorVsn = 0;
+  if (minorVsn) *minorVsn = 0;
+
+#ifdef WIN32
+  OSVERSIONINFO info;
+  memset(&info, 0, sizeof(OSVERSIONINFO));
+  info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+  if (GetVersionEx(&info))
   {
-    if (strcmp(wxOsVersion, "Win95") == 0)
-      return wxWIN95;
-    else if (strcmp(wxOsVersion, "Win32s") == 0)
-      return wxWIN32S;
-    else if (strcmp(wxOsVersion, "Windows") == 0)
-      return wxWINDOWS;
-    else if (strcmp(wxOsVersion, "WinNT") == 0)
-      return wxWINDOWS_NT;
-  }
-  bool  Win32s  = (( Version & 0x80000000 ) != 0);
-  bool  Win95   = (( Version & 0xFF ) >= 4);
-  bool  WinNT   = Version < 0x80000000;
-
-  // Get the version number
-  if (majorVsn)
-         *majorVsn = LOBYTE( lowWord );
-  if (minorVsn)
-         *minorVsn = HIBYTE( lowWord );
-
-  if (Win95)
-    return wxWIN95;
-  else if (Win32s)
+    if (majorVsn) *majorVsn = info.dwMajorVersion;
+    if (minorVsn) *minorVsn = info.dwMinorVersion;
+    switch (info.dwPlatformId)
+  {
+  case VER_PLATFORM_WIN32s:
     return wxWIN32S;
-  else if (WinNT)
+    break;
+  case VER_PLATFORM_WIN32_WINDOWS:
+    return wxWIN95;
+    break;
+  case VER_PLATFORM_WIN32_NT:
     return wxWINDOWS_NT;
-  else
-    return wxWINDOWS;
-    
-//  retValue = ((high & 0x8000)==0) ? wxWINDOWS_NT : wxWIN32S ;
-#endif
+    break;
+  }
+  }
+  return wxWINDOWS; // error if we get here, return generic value
+#else
+  // Win16 code...
+  int retValue ;
+#  ifdef __WINDOWS_386__
+  retValue = wxWIN386;
+#  else
+#    if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
+  extern HANDLE g_hPenWin;
+  retValue = g_hPenWin ? wxPENWINDOWS : wxWINDOWS ;
+#    endif
+#  endif
   // @@@@ To be completed. I don't have the manual here...
   if (majorVsn) *majorVsn = 3 ;
   if (minorVsn) *minorVsn = 1 ;
   return retValue ;
+#endif
 }
 
 // Reading and writing resources (eg WIN.INI, .Xdefaults)
-#if USE_RESOURCES
+#if wxUSE_RESOURCES
 bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
 {
   if (file != "")
@@ -576,7 +463,7 @@ bool wxGetResource(const wxString& section, const wxString& entry, int *value, c
   }
   else return FALSE;
 }
-#endif // USE_RESOURCES
+#endif // wxUSE_RESOURCES
 
 // Old cursor
 static HCURSOR wxBusyCursorOld = 0;
@@ -616,6 +503,64 @@ bool wxIsBusy(void)
   return (wxBusyCursorCount > 0);
 }    
 
+const char* wxGetHomeDir(wxString *pstr)
+{
+  wxString& strDir = *pstr;
+
+  #ifdef __UNIX__
+    const char *szHome = getenv("HOME");
+    if ( szHome == NULL ) {
+      // we're homeless...
+      wxLogWarning(_("can't find user's HOME, using current directory."));
+      strDir = ".";
+    }
+    else
+       strDir = szHome;
+
+    // add a trailing slash if needed
+    if ( strDir.Last() != '/' )
+      strDir << '/';
+  #else   // Windows
+    #ifdef  __WIN32__
+      const char *szHome = getenv("HOMEDRIVE");
+      if ( szHome != NULL )
+        strDir << szHome;
+      szHome = getenv("HOMEPATH");
+      if ( szHome != NULL ) {
+        strDir << szHome;
+
+        // the idea is that under NT these variables have default values
+        // of "%systemdrive%:" and "\\". As we don't want to create our
+        // config files in the root directory of the system drive, we will
+        // create it in our program's dir. However, if the user took care
+        // to set HOMEPATH to something other than "\\", we suppose that he
+        // knows what he is doing and use the supplied value.
+        if ( strcmp(szHome, "\\") != 0 )
+          return strDir.c_str();
+      }
+
+    #else   // Win16
+      // Win16 has no idea about home, so use the working 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);
+
+  #endif  // UNIX/Win
+
+  return strDir.c_str();
+}
+
 // Hack for MS-DOS
 char *wxGetUserHome (const wxString& user)
 {
@@ -626,14 +571,14 @@ char *wxGetUserHome (const wxString& user)
     char tmp[64];
     if (wxGetUserId(tmp, sizeof(tmp)/sizeof(char))) {
       // Guests belong in the temp dir
-      if (stricmp(tmp, "annonymous") == 0) {
-       if ((home = getenv("TMP")) != NULL ||
-           (home = getenv("TMPDIR")) != NULL ||
-           (home = getenv("TEMP")) != NULL)
-         return *home ? home : "\\";
+      if (Stricmp(tmp, "annonymous") == 0) {
+        if ((home = getenv("TMP")) != NULL ||
+            (home = getenv("TMPDIR")) != NULL ||
+            (home = getenv("TEMP")) != NULL)
+            return *home ? home : "\\";
       }
-      if (stricmp(tmp, WXSTRINGCAST user1) == 0)
-           user1 = "";
+      if (Stricmp(tmp, WXSTRINGCAST user1) == 0)
+        user1 = "";
     }
   }
   if (user1 == "")
@@ -650,25 +595,25 @@ char *wxGetUserHome (const wxString& user)
 // in long calculations.
 bool wxCheckForInterrupt(wxWindow *wnd)
 {
-       if(wnd){
-               MSG msg;
-               HWND win= (HWND) wnd->GetHWND();
-               while(PeekMessage(&msg,win,0,0,PM_REMOVE)){
-                       TranslateMessage(&msg);
-                       DispatchMessage(&msg);
-               }
-               return TRUE;//*** temporary?
-       }
-       else{
-               wxError("wnd==NULL !!!");
-               return FALSE;//*** temporary?
-       }
+  if(wnd){
+    MSG msg;
+    HWND win= (HWND) wnd->GetHWND();
+    while(PeekMessage(&msg,win,0,0,PM_REMOVE)){
+      TranslateMessage(&msg);
+      DispatchMessage(&msg);
+    }
+    return TRUE;//*** temporary?
+  }
+  else{
+    wxError("wnd==NULL !!!");
+    return FALSE;//*** temporary?
+  }
 }
 
 // MSW only: get user-defined resource from the .res file.
 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
 
-#ifdef __WINDOWS__
+#ifdef __WXMSW__
 char *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType)
 {
   char *s = NULL;
@@ -746,3 +691,206 @@ void wxDisplaySize(int *width, int *height)
   ReleaseDC(NULL, dc);
 }
 
+bool wxDirExists(const wxString& dir)
+{
+  /* MATTHEW: [6] Always use same code for Win32, call FindClose */
+#if defined(__WIN32__)
+  WIN32_FIND_DATA fileInfo;
+#else
+#ifdef __BORLANDC__
+  struct ffblk fileInfo;
+#else
+  struct find_t fileInfo;
+#endif
+#endif
+
+#if defined(__WIN32__)
+       HANDLE h = FindFirstFile((LPTSTR) WXSTRINGCAST dir,(LPWIN32_FIND_DATA)&fileInfo);
+
+       if (h==INVALID_HANDLE_VALUE)
+        return FALSE;
+       else {
+        FindClose(h);
+        return ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
+       }
+#else
+  // 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(WXSTRINGCAST dir, &fileInfo, _A_SUBDIR) == 0  && (fileInfo.ff_attrib & _A_SUBDIR) != 0));
+#else
+  return (((_dos_findfirst(WXSTRINGCAST dir, _A_SUBDIR, &fileInfo) == 0) && (fileInfo.attrib & _A_SUBDIR)) != 0);
+#endif
+#endif
+}
+
+wxString WXDLLEXPORT wxGetWindowText(WXHWND hWnd)
+{
+    wxString str;
+    int len = GetWindowTextLength((HWND)hWnd) + 1;
+    GetWindowText((HWND)hWnd, str.GetWriteBuf(len), len);
+    str.UngetWriteBuf();
+
+    return str;
+}
+
+#if 0
+//------------------------------------------------------------------------
+// wild character routines
+//------------------------------------------------------------------------
+
+bool wxIsWild( const wxString& pattern )
+{
+  wxString tmp = pattern;
+  char *pat = WXSTRINGCAST(tmp);
+    while (*pat) {
+       switch (*pat++) {
+       case '?': case '*': case '[': case '{':
+           return TRUE;
+       case '\\':
+           if (!*pat++)
+               return FALSE;
+       }
+    }
+    return FALSE;
+};
+
+
+bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
+{
+  wxString tmp1 = pat;
+  char *pattern = WXSTRINGCAST(tmp1);
+  wxString tmp2 = text;
+  char *str = WXSTRINGCAST(tmp2);
+    char c;
+    char *cp;
+    bool done = FALSE, ret_code, ok;
+    // Below is for vi fans
+    const char OB = '{', CB = '}';
+
+    // dot_special means '.' only matches '.'
+    if (dot_special && *str == '.' && *pattern != *str)
+       return FALSE;
+
+    while ((*pattern != '\0') && (!done)
+    && (((*str=='\0')&&((*pattern==OB)||(*pattern=='*')))||(*str!='\0'))) {
+       switch (*pattern) {
+       case '\\':
+           pattern++;
+           if (*pattern != '\0')
+               pattern++;
+           break;
+       case '*':
+           pattern++;
+           ret_code = FALSE;
+           while ((*str!='\0')
+           && (!(ret_code=wxMatchWild(pattern, str++, FALSE))))
+               /*loop*/;
+           if (ret_code) {
+               while (*str != '\0')
+                   str++;
+               while (*pattern != '\0')
+                   pattern++;
+           }
+           break;
+       case '[':
+           pattern++;
+         repeat:
+           if ((*pattern == '\0') || (*pattern == ']')) {
+               done = TRUE;
+               break;
+           }
+           if (*pattern == '\\') {
+               pattern++;
+               if (*pattern == '\0') {
+                   done = TRUE;
+                   break;
+               }
+           }
+           if (*(pattern + 1) == '-') {
+               c = *pattern;
+               pattern += 2;
+               if (*pattern == ']') {
+                   done = TRUE;
+                   break;
+               }
+               if (*pattern == '\\') {
+                   pattern++;
+                   if (*pattern == '\0') {
+                       done = TRUE;
+                       break;
+                   }
+               }
+               if ((*str < c) || (*str > *pattern)) {
+                   pattern++;
+                   goto repeat;
+               }
+           } else if (*pattern != *str) {
+               pattern++;
+               goto repeat;
+           }
+           pattern++;
+           while ((*pattern != ']') && (*pattern != '\0')) {
+               if ((*pattern == '\\') && (*(pattern + 1) != '\0'))
+                   pattern++;
+               pattern++;
+           }
+           if (*pattern != '\0') {
+               pattern++, str++;
+           }
+           break;
+       case '?':
+           pattern++;
+           str++;
+           break;
+       case OB:
+           pattern++;
+           while ((*pattern != CB) && (*pattern != '\0')) {
+               cp = str;
+               ok = TRUE;
+               while (ok && (*cp != '\0') && (*pattern != '\0')
+               &&  (*pattern != ',') && (*pattern != CB)) {
+                   if (*pattern == '\\')
+                       pattern++;
+                   ok = (*pattern++ == *cp++);
+               }
+               if (*pattern == '\0') {
+                   ok = FALSE;
+                   done = TRUE;
+                   break;
+               } else if (ok) {
+                   str = cp;
+                   while ((*pattern != CB) && (*pattern != '\0')) {
+                       if (*++pattern == '\\') {
+                           if (*++pattern == CB)
+                               pattern++;
+                       }
+                   }
+               } else {
+                   while (*pattern!=CB && *pattern!=',' && *pattern!='\0') {
+                       if (*++pattern == '\\') {
+                            if (*++pattern == CB || *pattern == ',')
+                               pattern++;
+                       }
+                   }
+               }
+               if (*pattern != '\0')
+                   pattern++;
+           }
+           break;
+       default:
+           if (*str == *pattern) {
+               str++, pattern++;
+           } else {
+               done = TRUE;
+           }
+       }
+    }
+    while (*pattern == '*')
+       pattern++;
+    return ((*str == '\0') && (*pattern == '\0'));
+};
+
+#endif
+