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