]> git.saurik.com Git - wxWidgets.git/blame - src/msw/utils.cpp
linux compile fix
[wxWidgets.git] / src / msw / utils.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: utils.cpp
3// Purpose: Various utilities
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
743e0a66 9// Licence: wxWindows license
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
a3b46648 13// #pragma implementation "utils.h" // Note: this is done in utilscmn.cpp now.
2bda0e17
KB
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include "wx/setup.h"
25#include "wx/utils.h"
26#include "wx/app.h"
27#include "wx/cursor.h"
743e0a66 28#endif //WX_PRECOMP
2bda0e17
KB
29
30#include "wx/msw/private.h"
31#include "wx/timer.h"
32
33#include <ctype.h>
34
35#ifndef __GNUWIN32__
36#include <direct.h>
37#include <dos.h>
743e0a66 38#endif //GNUWIN32
2bda0e17
KB
39
40#ifdef __GNUWIN32__
41#include <sys/unistd.h>
42#include <sys/stat.h>
743e0a66
VZ
43#endif //GNUWIN32
44
45#include "wx/log.h"
2bda0e17
KB
46
47#ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
48 // this (3.1 I believe) and how to test for it.
49 // If this works for Borland 4.0 as well, then no worries.
50#include <dir.h>
51#endif
52
53#ifdef __WIN32__
54#include <io.h>
55
56#ifndef __GNUWIN32__
57#include <shellapi.h>
58#endif
59#endif
60
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
64#ifndef __WATCOMC__
65#if !(defined(_MSC_VER) && (_MSC_VER > 800))
66#include <errno.h>
67#endif
68#endif
69#include <stdarg.h>
70
71// In the WIN.INI file
72static const char WX_SECTION[] = "wxWindows";
73static const char eHOSTNAME[] = "HostName";
74static const char eUSERID[] = "UserId";
75static const char eUSERNAME[] = "UserName";
76
2bda0e17
KB
77// For the following functions we SHOULD fill in support
78// for Windows-NT (which I don't know) as I assume it begin
79// a POSIX Unix (so claims MS) that it has some special
80// functions beyond those provided by WinSock
81
82// Get full hostname (eg. DoDo.BSn-Germany.crg.de)
83bool wxGetHostName(char *buf, int maxSize)
84{
85#ifdef __WIN32__
86 DWORD nSize = maxSize;
87 return (::GetComputerName(buf, &nSize) != 0);
88#else
89 char *sysname;
90 const char *default_host = "noname";
91
92 if ((sysname = getenv("SYSTEM_NAME")) == NULL) {
93 GetProfileString(WX_SECTION, eHOSTNAME, default_host, buf, maxSize - 1);
94 } else
95 strncpy(buf, sysname, maxSize - 1);
96 buf[maxSize] = '\0';
97 return *buf ? TRUE : FALSE;
98#endif
99}
100
101// Get user ID e.g. jacs
102bool wxGetUserId(char *buf, int maxSize)
103{
104#if defined(__WIN32__) && !defined(__win32s__) && 0
105 // Gets the current user's full name according to the MS article PSS ID
106 // Number: Q119670
107 // Seems to be the same as the login name for me?
108 char *UserName = new char[256];
109 char *Domain = new char[256];
110 DWORD maxCharacters = 255;
111 GetUserName( UserName, &maxCharacters );
112 GetComputerName( Domain, &maxCharacters );
113
114 WCHAR wszUserName[256]; // Unicode user name
115 WCHAR wszDomain[256];
116 LPBYTE ComputerName;
117
118 struct _SERVER_INFO_100 *si100; // Server structure
119 struct _USER_INFO_2 *ui; // User structure
120
121 // Convert ASCII user name and domain to Unicode.
122
123 MultiByteToWideChar( CP_ACP, 0, UserName,
124 strlen(UserName)+1, wszUserName, sizeof(wszUserName) );
125 MultiByteToWideChar( CP_ACP, 0, Domain,
126 strlen(Domain)+1, wszDomain, sizeof(wszDomain) );
127
128 // Get the computer name of a DC for the specified domain.
129 // >If you get a link error on this, include netapi32.lib<
130
131 NetGetDCName( NULL, wszDomain, &ComputerName );
132
133 // Look up the user on the DC.
134
135 if(NetUserGetInfo( (LPWSTR) ComputerName,
136 (LPWSTR) &wszUserName, 2, (LPBYTE *) &ui))
137 {
138 printf( "Error getting user information.\n" );
139 return( FALSE );
140 }
141
142 // Convert the Unicode full name to ASCII.
143
144 WideCharToMultiByte( CP_ACP, 0, ui->usri2_full_name,
145 -1, buf, 256, NULL, NULL );
146 }
147 return( TRUE );
148/*
149 DWORD nSize = maxSize;
150 return ::GetUserName(buf, &nSize);
151*/
152#else
153 char *user;
154 const char *default_id = "anonymous";
155
156 // Can't assume we have NIS (PC-NFS) or some other ID daemon
157 // So we ...
743e0a66
VZ
158 if ( (user = getenv("USER")) == NULL &&
159 (user = getenv("LOGNAME")) == NULL ) {
2bda0e17
KB
160 // Use wxWindows configuration data (comming soon)
161 GetProfileString(WX_SECTION, eUSERID, default_id, buf, maxSize - 1);
162 } else
163 strncpy(buf, user, maxSize - 1);
164 return *buf ? TRUE : FALSE;
165#endif
166}
167
168// Get user name e.g. Julian Smart
169bool wxGetUserName(char *buf, int maxSize)
170{
171 const char *default_name = "Unknown User";
172#if defined(__WIN32__)
173/*
174 DWORD nSize = maxSize;
175 In VC++ 4.0, results in unresolved symbol __imp__GetUserNameA
176 if (GetUserName(buf, &nSize))
177 return TRUE;
178 else
179*/
180 // Could use NIS, MS-Mail or other site specific programs
181 // Use wxWindows configuration data
182 GetProfileString(WX_SECTION, eUSERNAME, default_name, buf, maxSize - 1);
183 return *buf ? TRUE : FALSE;
184// }
185#else
47d67540 186#if !defined(__WATCOMC__) && !defined(__GNUWIN32__) && wxUSE_PENWINDOWS
81d66cf3
JS
187 extern HANDLE g_hPenWin; // PenWindows Running?
188 if (g_hPenWin)
2bda0e17
KB
189 {
190 // PenWindows Does have a user concept!
191 // Get the current owner of the recognizer
192 GetPrivateProfileString("Current", "User", default_name, wxBuffer, maxSize - 1, "PENWIN.INI");
193 strncpy(buf, wxBuffer, maxSize - 1);
194 }
195 else
196#endif
197 {
198 // Could use NIS, MS-Mail or other site specific programs
199 // Use wxWindows configuration data
200 GetProfileString(WX_SECTION, eUSERNAME, default_name, buf, maxSize - 1);
201 }
202 return *buf ? TRUE : FALSE;
203#endif
204}
205
2bda0e17
KB
206int wxKill(long pid, int sig)
207{
208 return 0;
209}
210
211//
212// Execute a program in an Interactive Shell
213//
214bool
215wxShell(const wxString& command)
216{
217 char *shell;
218 if ((shell = getenv("COMSPEC")) == NULL)
219 shell = "\\COMMAND.COM";
220
221 char tmp[255];
222 if (command != "")
223 sprintf(tmp, "%s /c %s", shell, WXSTRINGCAST command);
224 else
225 strcpy(tmp, shell);
226
227 return (wxExecute((char *)tmp, FALSE) != 0);
228}
229
230// Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
231long wxGetFreeMemory(void)
232{
233#if defined(__WIN32__) && !defined(__BORLANDC__)
234 MEMORYSTATUS memStatus;
235 memStatus.dwLength = sizeof(MEMORYSTATUS);
236 GlobalMemoryStatus(&memStatus);
237 return memStatus.dwAvailPhys;
238#else
239 return (long)GetFreeSpace(0);
240#endif
241}
242
243// Sleep for nSecs seconds. Attempt a Windows implementation using timers.
244static bool inTimer = FALSE;
245class wxSleepTimer: public wxTimer
246{
247 public:
248 inline void Notify(void)
249 {
250 inTimer = FALSE;
251 Stop();
252 }
253};
254
255static wxTimer *wxTheSleepTimer = NULL;
256
257void wxSleep(int nSecs)
258{
259#if 0 // WIN32 hangs app
260 Sleep( 1000*nSecs );
261#else
262 if (inTimer)
263 return;
264
265 wxTheSleepTimer = new wxSleepTimer;
266 inTimer = TRUE;
267 wxTheSleepTimer->Start(nSecs*1000);
268 while (inTimer)
269 {
270 if (wxTheApp->Pending())
271 wxTheApp->Dispatch();
272 }
273 delete wxTheSleepTimer;
274 wxTheSleepTimer = NULL;
275#endif
276}
277
278// Consume all events until no more left
279void wxFlushEvents(void)
280{
281// wxYield();
282}
283
284// Output a debug mess., in a system dependent fashion.
285void wxDebugMsg(const char *fmt ...)
286{
287 va_list ap;
288 static char buffer[512];
289
290 if (!wxTheApp->GetWantDebugOutput())
291 return ;
292
293 va_start(ap, fmt);
294
295 wvsprintf(buffer,fmt,ap) ;
296 OutputDebugString((LPCSTR)buffer) ;
297
298 va_end(ap);
299}
300
301// Non-fatal error: pop up message box and (possibly) continue
302void wxError(const wxString& msg, const wxString& title)
303{
304 sprintf(wxBuffer, "%s\nContinue?", WXSTRINGCAST msg);
305 if (MessageBox(NULL, (LPCSTR)wxBuffer, (LPCSTR)WXSTRINGCAST title,
306 MB_ICONSTOP | MB_YESNO) == IDNO)
307 wxExit();
308}
309
310// Fatal error: pop up message box and abort
311void wxFatalError(const wxString& msg, const wxString& title)
312{
313 sprintf(wxBuffer, "%s: %s", WXSTRINGCAST title, WXSTRINGCAST msg);
314 FatalAppExit(0, (LPCSTR)wxBuffer);
315}
316
317// Emit a beeeeeep
318void wxBell(void)
319{
320#ifdef __WIN32__
743e0a66 321 Beep(1000,1000) ; // 1kHz during 1 sec.
2bda0e17
KB
322#else
323 MessageBeep(-1) ;
324#endif
325}
326
6f65e337
JS
327// Chris Breeze 27/5/98: revised WIN32 code to
328// detect WindowsNT correctly
2bda0e17
KB
329int wxGetOsVersion(int *majorVsn, int *minorVsn)
330{
331 extern char *wxOsVersion;
6f65e337
JS
332 if (majorVsn) *majorVsn = 0;
333 if (minorVsn) *minorVsn = 0;
334
335#ifdef WIN32
336 OSVERSIONINFO info;
337 memset(&info, 0, sizeof(OSVERSIONINFO));
338 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
339 if (GetVersionEx(&info))
340 {
341 if (majorVsn) *majorVsn = info.dwMajorVersion;
342 if (minorVsn) *minorVsn = info.dwMinorVersion;
343 switch (info.dwPlatformId)
743e0a66
VZ
344 {
345 case VER_PLATFORM_WIN32s:
346 return wxWIN32S;
347 break;
348 case VER_PLATFORM_WIN32_WINDOWS:
349 return wxWIN95;
350 break;
351 case VER_PLATFORM_WIN32_NT:
352 return wxWINDOWS_NT;
353 break;
6f65e337 354 }
743e0a66
VZ
355 }
356 return wxWINDOWS; // error if we get here, return generic value
6f65e337
JS
357#else
358 // Win16 code...
2bda0e17 359 int retValue ;
6f65e337 360# ifdef __WINDOWS_386__
2bda0e17 361 retValue = wxWIN386;
6f65e337 362# else
47d67540 363# if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
81d66cf3
JS
364 extern HANDLE g_hPenWin;
365 retValue = g_hPenWin ? wxPENWINDOWS : wxWINDOWS ;
6f65e337
JS
366# endif
367# endif
2bda0e17
KB
368 // @@@@ To be completed. I don't have the manual here...
369 if (majorVsn) *majorVsn = 3 ;
370 if (minorVsn) *minorVsn = 1 ;
371 return retValue ;
6f65e337 372#endif
2bda0e17
KB
373}
374
375// Reading and writing resources (eg WIN.INI, .Xdefaults)
47d67540 376#if wxUSE_RESOURCES
2bda0e17
KB
377bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
378{
379 if (file != "")
380 return (WritePrivateProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)value, (LPCSTR)WXSTRINGCAST file) != 0);
381 else
382 return (WriteProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)WXSTRINGCAST value) != 0);
383}
384
385bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
386{
387 char buf[50];
388 sprintf(buf, "%.4f", value);
389 return wxWriteResource(section, entry, buf, file);
390}
391
392bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
393{
394 char buf[50];
395 sprintf(buf, "%ld", value);
396 return wxWriteResource(section, entry, buf, file);
397}
398
399bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
400{
401 char buf[50];
402 sprintf(buf, "%d", value);
403 return wxWriteResource(section, entry, buf, file);
404}
405
406bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file)
407{
408 static const char defunkt[] = "$$default";
409 if (file != "")
410 {
411 int n = GetPrivateProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)defunkt,
412 (LPSTR)wxBuffer, 1000, (LPCSTR)WXSTRINGCAST file);
413 if (n == 0 || strcmp(wxBuffer, defunkt) == 0)
414 return FALSE;
415 }
416 else
417 {
418 int n = GetProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)defunkt,
419 (LPSTR)wxBuffer, 1000);
420 if (n == 0 || strcmp(wxBuffer, defunkt) == 0)
421 return FALSE;
422 }
423 if (*value) delete[] (*value);
424 *value = copystring(wxBuffer);
425 return TRUE;
426 }
427
428bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
429{
430 char *s = NULL;
431 bool succ = wxGetResource(section, entry, (char **)&s, file);
432 if (succ)
433 {
434 *value = (float)strtod(s, NULL);
435 delete[] s;
436 return TRUE;
437 }
438 else return FALSE;
439}
440
441bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
442{
443 char *s = NULL;
444 bool succ = wxGetResource(section, entry, (char **)&s, file);
445 if (succ)
446 {
447 *value = strtol(s, NULL, 10);
448 delete[] s;
449 return TRUE;
450 }
451 else return FALSE;
452}
453
454bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
455{
456 char *s = NULL;
457 bool succ = wxGetResource(section, entry, (char **)&s, file);
458 if (succ)
459 {
460 *value = (int)strtol(s, NULL, 10);
461 delete[] s;
462 return TRUE;
463 }
464 else return FALSE;
465}
47d67540 466#endif // wxUSE_RESOURCES
2bda0e17
KB
467
468// Old cursor
469static HCURSOR wxBusyCursorOld = 0;
470static int wxBusyCursorCount = 0;
471
472// Set the cursor to the busy cursor for all windows
473void wxBeginBusyCursor(wxCursor *cursor)
474{
475 wxBusyCursorCount ++;
476 if (wxBusyCursorCount == 1)
477 {
478 wxBusyCursorOld = ::SetCursor((HCURSOR) cursor->GetHCURSOR());
479 }
480 else
481 {
482 (void)::SetCursor((HCURSOR) cursor->GetHCURSOR());
483 }
484}
485
486// Restore cursor to normal
487void wxEndBusyCursor(void)
488{
489 if (wxBusyCursorCount == 0)
490 return;
491
492 wxBusyCursorCount --;
493 if (wxBusyCursorCount == 0)
494 {
495 ::SetCursor(wxBusyCursorOld);
496 wxBusyCursorOld = 0;
497 }
498}
499
500// TRUE if we're between the above two calls
501bool wxIsBusy(void)
502{
503 return (wxBusyCursorCount > 0);
504}
505
184b5d99 506const char* wxGetHomeDir(wxString *pstr)
743e0a66
VZ
507{
508 wxString& strDir = *pstr;
509
510 #ifdef __UNIX__
511 const char *szHome = getenv("HOME");
512 if ( szHome == NULL ) {
513 // we're homeless...
514 wxLogWarning(_("can't find user's HOME, using current directory."));
515 strDir = ".";
516 }
517 else
518 strDir = szHome;
519
520 // add a trailing slash if needed
521 if ( strDir.Last() != '/' )
522 strDir << '/';
523 #else // Windows
524 #ifdef __WIN32__
525 const char *szHome = getenv("HOMEDRIVE");
526 if ( szHome != NULL )
527 strDir << szHome;
528 szHome = getenv("HOMEPATH");
529 if ( szHome != NULL ) {
530 strDir << szHome;
531
532 // the idea is that under NT these variables have default values
533 // of "%systemdrive%:" and "\\". As we don't want to create our
534 // config files in the root directory of the system drive, we will
535 // create it in our program's dir. However, if the user took care
536 // to set HOMEPATH to something other than "\\", we suppose that he
537 // knows what he is doing and use the supplied value.
538 if ( strcmp(szHome, "\\") != 0 )
539 return strDir.c_str();
540 }
541
542 #else // Win16
543 // Win16 has no idea about home, so use the working directory instead
544 #endif // WIN16/32
545
546 // 260 was taken from windef.h
547 #ifndef MAX_PATH
548 #define MAX_PATH 260
549 #endif
550
551 wxString strPath;
552 ::GetModuleFileName(::GetModuleHandle(NULL),
553 strPath.GetWriteBuf(MAX_PATH), MAX_PATH);
554 strPath.UngetWriteBuf();
555
556 // extract the dir name
557 wxSplitPath(strPath, &strDir, NULL, NULL);
558
559 #endif // UNIX/Win
560
561 return strDir.c_str();
562}
563
2bda0e17
KB
564// Hack for MS-DOS
565char *wxGetUserHome (const wxString& user)
566{
567 char *home;
568 wxString user1(user);
569
570 if (user1 != "") {
571 char tmp[64];
572 if (wxGetUserId(tmp, sizeof(tmp)/sizeof(char))) {
573 // Guests belong in the temp dir
743e0a66
VZ
574 if (Stricmp(tmp, "annonymous") == 0) {
575 if ((home = getenv("TMP")) != NULL ||
576 (home = getenv("TMPDIR")) != NULL ||
577 (home = getenv("TEMP")) != NULL)
578 return *home ? home : "\\";
2bda0e17 579 }
743e0a66
VZ
580 if (Stricmp(tmp, WXSTRINGCAST user1) == 0)
581 user1 = "";
2bda0e17
KB
582 }
583 }
584 if (user1 == "")
585 if ((home = getenv("HOME")) != NULL)
586 {
587 strcpy(wxBuffer, home);
588 Unix2DosFilename(wxBuffer);
589 return wxBuffer;
590 }
591 return NULL; // No home known!
592}
593
594// Check whether this window wants to process messages, e.g. Stop button
595// in long calculations.
596bool wxCheckForInterrupt(wxWindow *wnd)
597{
743e0a66
VZ
598 if(wnd){
599 MSG msg;
600 HWND win= (HWND) wnd->GetHWND();
601 while(PeekMessage(&msg,win,0,0,PM_REMOVE)){
602 TranslateMessage(&msg);
603 DispatchMessage(&msg);
604 }
605 return TRUE;//*** temporary?
606 }
607 else{
608 wxError("wnd==NULL !!!");
609 return FALSE;//*** temporary?
610 }
2bda0e17
KB
611}
612
613// MSW only: get user-defined resource from the .res file.
614// Returns NULL or newly-allocated memory, so use delete[] to clean up.
615
2049ba38 616#ifdef __WXMSW__
2bda0e17
KB
617char *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType)
618{
619 char *s = NULL;
620#ifndef __WIN32__
621 HRSRC hResource = ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
622#else
623#ifdef UNICODE
624 HRSRC hResource = ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
625#else
626 HRSRC hResource = ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
627#endif
628#endif
629
630 if (hResource == 0)
631 return NULL;
632 HGLOBAL hData = ::LoadResource(wxGetInstance(), hResource);
633 if (hData == 0)
634 return NULL;
635 char *theText = (char *)LockResource(hData);
636 if (!theText)
637 return NULL;
638
639 s = copystring(theText);
640
641 // Obsolete in WIN32
642#ifndef __WIN32__
643 UnlockResource(hData);
644#endif
645
646 // No need??
647// GlobalFree(hData);
648
649 return s;
650}
651#endif
652
653void wxGetMousePosition( int* x, int* y )
654{
655 POINT pt;
656 GetCursorPos( & pt );
657 *x = pt.x;
658 *y = pt.y;
659};
660
661// Return TRUE if we have a colour display
662bool wxColourDisplay(void)
663{
664 HDC dc = ::GetDC(NULL);
665 bool flag;
666 int noCols = GetDeviceCaps(dc, NUMCOLORS);
667 if ((noCols == -1) || (noCols > 2))
668 flag = TRUE;
669 else
670 flag = FALSE;
671 ReleaseDC(NULL, dc);
672 return flag;
673}
674
675// Returns depth of screen
676int wxDisplayDepth(void)
677{
678 HDC dc = ::GetDC(NULL);
679 int planes = GetDeviceCaps(dc, PLANES);
680 int bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
681 int depth = planes*bitsPerPixel;
682 ReleaseDC(NULL, dc);
683 return depth;
684}
685
686// Get size of display
687void wxDisplaySize(int *width, int *height)
688{
689 HDC dc = ::GetDC(NULL);
690 *width = GetDeviceCaps(dc, HORZRES); *height = GetDeviceCaps(dc, VERTRES);
691 ReleaseDC(NULL, dc);
692}
693
7f555861
JS
694bool wxDirExists(const wxString& dir)
695{
696 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
697#if defined(__WIN32__)
698 WIN32_FIND_DATA fileInfo;
699#else
700#ifdef __BORLANDC__
701 struct ffblk fileInfo;
702#else
703 struct find_t fileInfo;
704#endif
705#endif
706
707#if defined(__WIN32__)
708 HANDLE h = FindFirstFile((LPTSTR) WXSTRINGCAST dir,(LPWIN32_FIND_DATA)&fileInfo);
709
710 if (h==INVALID_HANDLE_VALUE)
711 return FALSE;
712 else {
713 FindClose(h);
714 return ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
715 }
716#else
717 // In Borland findfirst has a different argument
718 // ordering from _dos_findfirst. But _dos_findfirst
719 // _should_ be ok in both MS and Borland... why not?
720#ifdef __BORLANDC__
721 return ((findfirst(WXSTRINGCAST dir, &fileInfo, _A_SUBDIR) == 0 && (fileInfo.ff_attrib & _A_SUBDIR) != 0));
722#else
723 return (((_dos_findfirst(WXSTRINGCAST dir, _A_SUBDIR, &fileInfo) == 0) && (fileInfo.attrib & _A_SUBDIR)) != 0);
724#endif
725#endif
726}
727
1c4a764c
VZ
728wxString WXDLLEXPORT wxGetWindowText(WXHWND hWnd)
729{
730 wxString str;
731 int len = GetWindowTextLength((HWND)hWnd) + 1;
732 GetWindowText((HWND)hWnd, str.GetWriteBuf(len), len);
733 str.UngetWriteBuf();
734
735 return str;
736}
737
7f555861
JS
738#if 0
739//------------------------------------------------------------------------
740// wild character routines
741//------------------------------------------------------------------------
742
743bool wxIsWild( const wxString& pattern )
744{
745 wxString tmp = pattern;
746 char *pat = WXSTRINGCAST(tmp);
747 while (*pat) {
748 switch (*pat++) {
749 case '?': case '*': case '[': case '{':
750 return TRUE;
751 case '\\':
752 if (!*pat++)
753 return FALSE;
754 }
755 }
756 return FALSE;
757};
758
759
760bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
761{
762 wxString tmp1 = pat;
763 char *pattern = WXSTRINGCAST(tmp1);
764 wxString tmp2 = text;
765 char *str = WXSTRINGCAST(tmp2);
766 char c;
767 char *cp;
768 bool done = FALSE, ret_code, ok;
769 // Below is for vi fans
770 const char OB = '{', CB = '}';
771
772 // dot_special means '.' only matches '.'
773 if (dot_special && *str == '.' && *pattern != *str)
774 return FALSE;
775
776 while ((*pattern != '\0') && (!done)
777 && (((*str=='\0')&&((*pattern==OB)||(*pattern=='*')))||(*str!='\0'))) {
778 switch (*pattern) {
779 case '\\':
780 pattern++;
781 if (*pattern != '\0')
782 pattern++;
783 break;
784 case '*':
785 pattern++;
786 ret_code = FALSE;
787 while ((*str!='\0')
788 && (!(ret_code=wxMatchWild(pattern, str++, FALSE))))
789 /*loop*/;
790 if (ret_code) {
791 while (*str != '\0')
792 str++;
793 while (*pattern != '\0')
794 pattern++;
795 }
796 break;
797 case '[':
798 pattern++;
799 repeat:
800 if ((*pattern == '\0') || (*pattern == ']')) {
801 done = TRUE;
802 break;
803 }
804 if (*pattern == '\\') {
805 pattern++;
806 if (*pattern == '\0') {
807 done = TRUE;
808 break;
809 }
810 }
811 if (*(pattern + 1) == '-') {
812 c = *pattern;
813 pattern += 2;
814 if (*pattern == ']') {
815 done = TRUE;
816 break;
817 }
818 if (*pattern == '\\') {
819 pattern++;
820 if (*pattern == '\0') {
821 done = TRUE;
822 break;
823 }
824 }
825 if ((*str < c) || (*str > *pattern)) {
826 pattern++;
827 goto repeat;
828 }
829 } else if (*pattern != *str) {
830 pattern++;
831 goto repeat;
832 }
833 pattern++;
834 while ((*pattern != ']') && (*pattern != '\0')) {
835 if ((*pattern == '\\') && (*(pattern + 1) != '\0'))
836 pattern++;
837 pattern++;
838 }
839 if (*pattern != '\0') {
840 pattern++, str++;
841 }
842 break;
843 case '?':
844 pattern++;
845 str++;
846 break;
847 case OB:
848 pattern++;
849 while ((*pattern != CB) && (*pattern != '\0')) {
850 cp = str;
851 ok = TRUE;
852 while (ok && (*cp != '\0') && (*pattern != '\0')
853 && (*pattern != ',') && (*pattern != CB)) {
854 if (*pattern == '\\')
855 pattern++;
856 ok = (*pattern++ == *cp++);
857 }
858 if (*pattern == '\0') {
859 ok = FALSE;
860 done = TRUE;
861 break;
862 } else if (ok) {
863 str = cp;
864 while ((*pattern != CB) && (*pattern != '\0')) {
865 if (*++pattern == '\\') {
866 if (*++pattern == CB)
867 pattern++;
868 }
869 }
870 } else {
871 while (*pattern!=CB && *pattern!=',' && *pattern!='\0') {
872 if (*++pattern == '\\') {
873 if (*++pattern == CB || *pattern == ',')
874 pattern++;
875 }
876 }
877 }
878 if (*pattern != '\0')
879 pattern++;
880 }
881 break;
882 default:
883 if (*str == *pattern) {
884 str++, pattern++;
885 } else {
886 done = TRUE;
887 }
888 }
889 }
890 while (*pattern == '*')
891 pattern++;
892 return ((*str == '\0') && (*pattern == '\0'));
893};
894
895#endif
896
a0a302dc
JS
897#if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
898
899/*
900When I started programming with Visual C++ v4.0, I missed one of my favorite
901tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
902on MSDN was a step in the right direction, but it is a console application
903and thus has limited features and extensibility. DBWIN32 is my creation
904to solve this problem.
905
906The code is essentially a merging of a stripped down version of the DBWIN code
907from VC 1.5 and DBMON.C with a few 32 bit changes.
908
909As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
910built into the operating system and works just by running DBWIN32. The Win95
911team decided not to support this hook, so I have provided code that will do
912this for you. See the file WIN95.TXT for instructions on installing this.
913
914If you have questions, problems or suggestions about DBWIN32, I welcome your
915feedback and plan to actively maintain the code.
916
917Andrew Tucker
918ast@halcyon.com
919
920To download dbwin32, see e.g.:
921
922http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
923*/
924
925#include <process.h>
926
927void OutputDebugStringW95(const char* lpOutputString, ...)
928{
929 HANDLE heventDBWIN; /* DBWIN32 synchronization object */
930 HANDLE heventData; /* data passing synch object */
931 HANDLE hSharedFile; /* memory mapped file shared data */
932 LPSTR lpszSharedMem;
933 char achBuffer[500];
934
935 /* create the output buffer */
936 va_list args;
937 va_start(args, lpOutputString);
938 vsprintf(achBuffer, lpOutputString, args);
939 va_end(args);
940
941 /*
942 Do a regular OutputDebugString so that the output is
943 still seen in the debugger window if it exists.
944
945 This ifdef is necessary to avoid infinite recursion
946 from the inclusion of W95TRACE.H
947 */
948#ifdef _UNICODE
949 ::OutputDebugStringW(achBuffer);
950#else
951 ::OutputDebugStringA(achBuffer);
952#endif
953
954 /* bail if it's not Win95 */
955 {
956 OSVERSIONINFO VerInfo;
957 VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
958 GetVersionEx(&VerInfo);
959 if ( VerInfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS )
960 return;
961 }
962
963 /* make sure DBWIN is open and waiting */
964 heventDBWIN = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_BUFFER_READY");
965 if ( !heventDBWIN )
966 {
967 //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
968 return;
969 }
970
971 /* get a handle to the data synch object */
972 heventData = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_DATA_READY");
973 if ( !heventData )
974 {
975 // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
976 CloseHandle(heventDBWIN);
977 return;
978 }
979
980 hSharedFile = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0, 4096, "DBWIN_BUFFER");
981 if (!hSharedFile)
982 {
983 //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
984 CloseHandle(heventDBWIN);
985 CloseHandle(heventData);
986 return;
987 }
988
989 lpszSharedMem = (LPSTR)MapViewOfFile(hSharedFile, FILE_MAP_WRITE, 0, 0, 512);
990 if (!lpszSharedMem)
991 {
992 //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
993 CloseHandle(heventDBWIN);
994 CloseHandle(heventData);
995 return;
996 }
997
998 /* wait for buffer event */
999 WaitForSingleObject(heventDBWIN, INFINITE);
1000
1001 /* write it to the shared memory */
1002#ifdef __BORLANDC__
1003 *((LPDWORD)lpszSharedMem) = getpid();
1004#else
1005 *((LPDWORD)lpszSharedMem) = _getpid();
1006#endif
1007
1008 wsprintf(lpszSharedMem + sizeof(DWORD), "%s", achBuffer);
1009
1010 /* signal data ready event */
1011 SetEvent(heventData);
1012
1013 /* clean up handles */
1014 CloseHandle(hSharedFile);
1015 CloseHandle(heventData);
1016 CloseHandle(heventDBWIN);
1017
1018 return;
1019}
1020
1021
1022#endif
1023