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