]> git.saurik.com Git - wxWidgets.git/blame - src/msw/utils.cpp
Added dummy OnIdle to wxWindow in wxGTK; doc tweaks
[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
ce3ed50d 38#if !defined(__GNUWIN32__) && !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
59#ifdef __WIN32__
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
302void wxSleep(int nSecs)
303{
304#if 0 // WIN32 hangs app
305 Sleep( 1000*nSecs );
306#else
307 if (inTimer)
308 return;
309
310 wxTheSleepTimer = new wxSleepTimer;
311 inTimer = TRUE;
312 wxTheSleepTimer->Start(nSecs*1000);
313 while (inTimer)
314 {
315 if (wxTheApp->Pending())
316 wxTheApp->Dispatch();
317 }
318 delete wxTheSleepTimer;
319 wxTheSleepTimer = NULL;
320#endif
321}
322
323// Consume all events until no more left
634903fd 324void wxFlushEvents()
2bda0e17
KB
325{
326// wxYield();
327}
328
329// Output a debug mess., in a system dependent fashion.
330void wxDebugMsg(const char *fmt ...)
331{
332 va_list ap;
333 static char buffer[512];
334
335 if (!wxTheApp->GetWantDebugOutput())
336 return ;
337
338 va_start(ap, fmt);
339
340 wvsprintf(buffer,fmt,ap) ;
341 OutputDebugString((LPCSTR)buffer) ;
342
343 va_end(ap);
344}
345
346// Non-fatal error: pop up message box and (possibly) continue
347void wxError(const wxString& msg, const wxString& title)
348{
349 sprintf(wxBuffer, "%s\nContinue?", WXSTRINGCAST msg);
350 if (MessageBox(NULL, (LPCSTR)wxBuffer, (LPCSTR)WXSTRINGCAST title,
351 MB_ICONSTOP | MB_YESNO) == IDNO)
352 wxExit();
353}
354
355// Fatal error: pop up message box and abort
356void wxFatalError(const wxString& msg, const wxString& title)
357{
358 sprintf(wxBuffer, "%s: %s", WXSTRINGCAST title, WXSTRINGCAST msg);
359 FatalAppExit(0, (LPCSTR)wxBuffer);
360}
361
362// Emit a beeeeeep
634903fd 363void wxBell()
2bda0e17 364{
b07135ba
RD
365 // Removed by RD because IHMO syncronous sound is a Bad Thing. MessageBeep
366 // will do a similar thing anyway if there is no sound card...
367//#ifdef __WIN32__
368// Beep(1000,1000) ; // 1kHz during 1 sec.
369//#else
ce200637 370 MessageBeep((UINT)-1) ;
b07135ba 371//#endif
2bda0e17
KB
372}
373
6f65e337
JS
374// Chris Breeze 27/5/98: revised WIN32 code to
375// detect WindowsNT correctly
2bda0e17
KB
376int wxGetOsVersion(int *majorVsn, int *minorVsn)
377{
378 extern char *wxOsVersion;
6f65e337
JS
379 if (majorVsn) *majorVsn = 0;
380 if (minorVsn) *minorVsn = 0;
381
2432b92d 382#if defined(__WIN32__) && !defined(__SC__)
6f65e337
JS
383 OSVERSIONINFO info;
384 memset(&info, 0, sizeof(OSVERSIONINFO));
385 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
386 if (GetVersionEx(&info))
387 {
388 if (majorVsn) *majorVsn = info.dwMajorVersion;
389 if (minorVsn) *minorVsn = info.dwMinorVersion;
390 switch (info.dwPlatformId)
743e0a66
VZ
391 {
392 case VER_PLATFORM_WIN32s:
393 return wxWIN32S;
394 break;
395 case VER_PLATFORM_WIN32_WINDOWS:
396 return wxWIN95;
397 break;
398 case VER_PLATFORM_WIN32_NT:
399 return wxWINDOWS_NT;
400 break;
6f65e337 401 }
743e0a66
VZ
402 }
403 return wxWINDOWS; // error if we get here, return generic value
6f65e337
JS
404#else
405 // Win16 code...
2432b92d 406 int retValue = 0;
6f65e337 407# ifdef __WINDOWS_386__
2bda0e17 408 retValue = wxWIN386;
6f65e337 409# else
47d67540 410# if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
81d66cf3
JS
411 extern HANDLE g_hPenWin;
412 retValue = g_hPenWin ? wxPENWINDOWS : wxWINDOWS ;
6f65e337
JS
413# endif
414# endif
2bda0e17
KB
415 // @@@@ To be completed. I don't have the manual here...
416 if (majorVsn) *majorVsn = 3 ;
417 if (minorVsn) *minorVsn = 1 ;
418 return retValue ;
6f65e337 419#endif
2bda0e17
KB
420}
421
422// Reading and writing resources (eg WIN.INI, .Xdefaults)
47d67540 423#if wxUSE_RESOURCES
2bda0e17
KB
424bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
425{
426 if (file != "")
427 return (WritePrivateProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)value, (LPCSTR)WXSTRINGCAST file) != 0);
428 else
429 return (WriteProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)WXSTRINGCAST value) != 0);
430}
431
432bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
433{
434 char buf[50];
435 sprintf(buf, "%.4f", value);
436 return wxWriteResource(section, entry, buf, file);
437}
438
439bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
440{
441 char buf[50];
442 sprintf(buf, "%ld", value);
443 return wxWriteResource(section, entry, buf, file);
444}
445
446bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
447{
448 char buf[50];
449 sprintf(buf, "%d", value);
450 return wxWriteResource(section, entry, buf, file);
451}
452
453bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file)
454{
455 static const char defunkt[] = "$$default";
456 if (file != "")
457 {
458 int n = GetPrivateProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)defunkt,
459 (LPSTR)wxBuffer, 1000, (LPCSTR)WXSTRINGCAST file);
460 if (n == 0 || strcmp(wxBuffer, defunkt) == 0)
461 return FALSE;
462 }
463 else
464 {
465 int n = GetProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)defunkt,
466 (LPSTR)wxBuffer, 1000);
467 if (n == 0 || strcmp(wxBuffer, defunkt) == 0)
468 return FALSE;
469 }
470 if (*value) delete[] (*value);
471 *value = copystring(wxBuffer);
472 return TRUE;
473 }
474
475bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
476{
477 char *s = NULL;
478 bool succ = wxGetResource(section, entry, (char **)&s, file);
479 if (succ)
480 {
481 *value = (float)strtod(s, NULL);
482 delete[] s;
483 return TRUE;
484 }
485 else return FALSE;
486}
487
488bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
489{
490 char *s = NULL;
491 bool succ = wxGetResource(section, entry, (char **)&s, file);
492 if (succ)
493 {
494 *value = strtol(s, NULL, 10);
495 delete[] s;
496 return TRUE;
497 }
498 else return FALSE;
499}
500
501bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
502{
503 char *s = NULL;
504 bool succ = wxGetResource(section, entry, (char **)&s, file);
505 if (succ)
506 {
507 *value = (int)strtol(s, NULL, 10);
b07135ba 508 delete[] s;
2bda0e17
KB
509 return TRUE;
510 }
511 else return FALSE;
512}
47d67540 513#endif // wxUSE_RESOURCES
2bda0e17 514
634903fd
VZ
515// ---------------------------------------------------------------------------
516// helper functiosn for showing a "busy" cursor
517// ---------------------------------------------------------------------------
518
519extern HCURSOR gs_wxBusyCursor = 0; // new, busy cursor
520static HCURSOR gs_wxBusyCursorOld = 0; // old cursor
521static int gs_wxBusyCursorCount = 0;
2bda0e17
KB
522
523// Set the cursor to the busy cursor for all windows
524void wxBeginBusyCursor(wxCursor *cursor)
525{
634903fd
VZ
526 if ( gs_wxBusyCursorCount++ == 0 )
527 {
528 gs_wxBusyCursor = (HCURSOR)cursor->GetHCURSOR();
529 gs_wxBusyCursorOld = ::SetCursor(gs_wxBusyCursor);
530 }
531 //else: nothing to do, already set
2bda0e17
KB
532}
533
534// Restore cursor to normal
634903fd 535void wxEndBusyCursor()
2bda0e17 536{
634903fd
VZ
537 wxCHECK_RET( gs_wxBusyCursorCount > 0,
538 "no matching wxBeginBusyCursor() for wxEndBusyCursor()" );
b07135ba 539
634903fd
VZ
540 if ( --gs_wxBusyCursorCount == 0 )
541 {
542 ::SetCursor(gs_wxBusyCursorOld);
543
544 gs_wxBusyCursorOld = 0;
545 }
2bda0e17
KB
546}
547
548// TRUE if we're between the above two calls
634903fd 549bool wxIsBusy()
2bda0e17 550{
634903fd 551 return (gs_wxBusyCursorCount > 0);
b07135ba 552}
2bda0e17 553
634903fd 554// ---------------------------------------------------------------------------
184b5d99 555const char* wxGetHomeDir(wxString *pstr)
743e0a66
VZ
556{
557 wxString& strDir = *pstr;
558
57c208c5 559 #if defined(__UNIX__) && !defined(__TWIN32__)
743e0a66
VZ
560 const char *szHome = getenv("HOME");
561 if ( szHome == NULL ) {
562 // we're homeless...
563 wxLogWarning(_("can't find user's HOME, using current directory."));
564 strDir = ".";
565 }
566 else
567 strDir = szHome;
568
569 // add a trailing slash if needed
570 if ( strDir.Last() != '/' )
571 strDir << '/';
572 #else // Windows
573 #ifdef __WIN32__
574 const char *szHome = getenv("HOMEDRIVE");
575 if ( szHome != NULL )
576 strDir << szHome;
577 szHome = getenv("HOMEPATH");
578 if ( szHome != NULL ) {
579 strDir << szHome;
580
581 // the idea is that under NT these variables have default values
582 // of "%systemdrive%:" and "\\". As we don't want to create our
583 // config files in the root directory of the system drive, we will
584 // create it in our program's dir. However, if the user took care
585 // to set HOMEPATH to something other than "\\", we suppose that he
586 // knows what he is doing and use the supplied value.
587 if ( strcmp(szHome, "\\") != 0 )
588 return strDir.c_str();
589 }
590
591 #else // Win16
592 // Win16 has no idea about home, so use the working directory instead
593 #endif // WIN16/32
594
595 // 260 was taken from windef.h
596 #ifndef MAX_PATH
597 #define MAX_PATH 260
598 #endif
599
600 wxString strPath;
601 ::GetModuleFileName(::GetModuleHandle(NULL),
602 strPath.GetWriteBuf(MAX_PATH), MAX_PATH);
603 strPath.UngetWriteBuf();
604
605 // extract the dir name
606 wxSplitPath(strPath, &strDir, NULL, NULL);
607
608 #endif // UNIX/Win
609
610 return strDir.c_str();
611}
612
2bda0e17
KB
613// Hack for MS-DOS
614char *wxGetUserHome (const wxString& user)
615{
616 char *home;
617 wxString user1(user);
618
619 if (user1 != "") {
620 char tmp[64];
621 if (wxGetUserId(tmp, sizeof(tmp)/sizeof(char))) {
622 // Guests belong in the temp dir
743e0a66
VZ
623 if (Stricmp(tmp, "annonymous") == 0) {
624 if ((home = getenv("TMP")) != NULL ||
625 (home = getenv("TMPDIR")) != NULL ||
626 (home = getenv("TEMP")) != NULL)
627 return *home ? home : "\\";
2bda0e17 628 }
743e0a66
VZ
629 if (Stricmp(tmp, WXSTRINGCAST user1) == 0)
630 user1 = "";
2bda0e17
KB
631 }
632 }
633 if (user1 == "")
634 if ((home = getenv("HOME")) != NULL)
635 {
636 strcpy(wxBuffer, home);
637 Unix2DosFilename(wxBuffer);
638 return wxBuffer;
639 }
640 return NULL; // No home known!
641}
642
643// Check whether this window wants to process messages, e.g. Stop button
644// in long calculations.
645bool wxCheckForInterrupt(wxWindow *wnd)
646{
743e0a66
VZ
647 if(wnd){
648 MSG msg;
649 HWND win= (HWND) wnd->GetHWND();
650 while(PeekMessage(&msg,win,0,0,PM_REMOVE)){
651 TranslateMessage(&msg);
652 DispatchMessage(&msg);
653 }
654 return TRUE;//*** temporary?
655 }
656 else{
634903fd
VZ
657 wxFAIL_MSG("wnd==NULL !!!");
658
743e0a66
VZ
659 return FALSE;//*** temporary?
660 }
2bda0e17
KB
661}
662
663// MSW only: get user-defined resource from the .res file.
664// Returns NULL or newly-allocated memory, so use delete[] to clean up.
665
2049ba38 666#ifdef __WXMSW__
2bda0e17
KB
667char *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType)
668{
669 char *s = NULL;
57c208c5 670#if !defined(__WIN32__) || defined(__TWIN32__)
2bda0e17
KB
671 HRSRC hResource = ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
672#else
673#ifdef UNICODE
674 HRSRC hResource = ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
675#else
676 HRSRC hResource = ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
677#endif
678#endif
679
680 if (hResource == 0)
681 return NULL;
682 HGLOBAL hData = ::LoadResource(wxGetInstance(), hResource);
683 if (hData == 0)
684 return NULL;
685 char *theText = (char *)LockResource(hData);
686 if (!theText)
687 return NULL;
b07135ba 688
2bda0e17
KB
689 s = copystring(theText);
690
691 // Obsolete in WIN32
692#ifndef __WIN32__
693 UnlockResource(hData);
694#endif
695
696 // No need??
697// GlobalFree(hData);
698
699 return s;
700}
701#endif
702
703void wxGetMousePosition( int* x, int* y )
704{
705 POINT pt;
706 GetCursorPos( & pt );
707 *x = pt.x;
708 *y = pt.y;
709};
710
711// Return TRUE if we have a colour display
634903fd 712bool wxColourDisplay()
2bda0e17 713{
57c208c5 714 HDC dc = ::GetDC((HWND) NULL);
2bda0e17
KB
715 bool flag;
716 int noCols = GetDeviceCaps(dc, NUMCOLORS);
717 if ((noCols == -1) || (noCols > 2))
718 flag = TRUE;
719 else
720 flag = FALSE;
57c208c5 721 ReleaseDC((HWND) NULL, dc);
2bda0e17
KB
722 return flag;
723}
724
725// Returns depth of screen
634903fd 726int wxDisplayDepth()
2bda0e17 727{
57c208c5 728 HDC dc = ::GetDC((HWND) NULL);
2bda0e17
KB
729 int planes = GetDeviceCaps(dc, PLANES);
730 int bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
731 int depth = planes*bitsPerPixel;
57c208c5 732 ReleaseDC((HWND) NULL, dc);
2bda0e17
KB
733 return depth;
734}
735
736// Get size of display
737void wxDisplaySize(int *width, int *height)
738{
57c208c5 739 HDC dc = ::GetDC((HWND) NULL);
2bda0e17 740 *width = GetDeviceCaps(dc, HORZRES); *height = GetDeviceCaps(dc, VERTRES);
57c208c5 741 ReleaseDC((HWND) NULL, dc);
2bda0e17
KB
742}
743
7f555861
JS
744bool wxDirExists(const wxString& dir)
745{
746 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
747#if defined(__WIN32__)
748 WIN32_FIND_DATA fileInfo;
749#else
750#ifdef __BORLANDC__
751 struct ffblk fileInfo;
752#else
753 struct find_t fileInfo;
754#endif
755#endif
756
757#if defined(__WIN32__)
3f4a0c5b
VZ
758 HANDLE h = FindFirstFile((LPTSTR) WXSTRINGCAST dir,(LPWIN32_FIND_DATA)&fileInfo);
759
760 if (h==INVALID_HANDLE_VALUE)
761 return FALSE;
762 else {
763 FindClose(h);
764 return ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
765 }
7f555861
JS
766#else
767 // In Borland findfirst has a different argument
768 // ordering from _dos_findfirst. But _dos_findfirst
769 // _should_ be ok in both MS and Borland... why not?
770#ifdef __BORLANDC__
771 return ((findfirst(WXSTRINGCAST dir, &fileInfo, _A_SUBDIR) == 0 && (fileInfo.ff_attrib & _A_SUBDIR) != 0));
772#else
773 return (((_dos_findfirst(WXSTRINGCAST dir, _A_SUBDIR, &fileInfo) == 0) && (fileInfo.attrib & _A_SUBDIR)) != 0);
774#endif
775#endif
776}
777
1c4a764c
VZ
778wxString WXDLLEXPORT wxGetWindowText(WXHWND hWnd)
779{
780 wxString str;
781 int len = GetWindowTextLength((HWND)hWnd) + 1;
782 GetWindowText((HWND)hWnd, str.GetWriteBuf(len), len);
783 str.UngetWriteBuf();
784
785 return str;
786}
787
7f555861
JS
788#if 0
789//------------------------------------------------------------------------
790// wild character routines
791//------------------------------------------------------------------------
792
793bool wxIsWild( const wxString& pattern )
794{
795 wxString tmp = pattern;
796 char *pat = WXSTRINGCAST(tmp);
797 while (*pat) {
3f4a0c5b
VZ
798 switch (*pat++) {
799 case '?': case '*': case '[': case '{':
800 return TRUE;
801 case '\\':
802 if (!*pat++)
803 return FALSE;
804 }
7f555861
JS
805 }
806 return FALSE;
807};
808
809
810bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
811{
812 wxString tmp1 = pat;
813 char *pattern = WXSTRINGCAST(tmp1);
814 wxString tmp2 = text;
815 char *str = WXSTRINGCAST(tmp2);
816 char c;
817 char *cp;
818 bool done = FALSE, ret_code, ok;
819 // Below is for vi fans
820 const char OB = '{', CB = '}';
821
822 // dot_special means '.' only matches '.'
823 if (dot_special && *str == '.' && *pattern != *str)
3f4a0c5b 824 return FALSE;
7f555861
JS
825
826 while ((*pattern != '\0') && (!done)
827 && (((*str=='\0')&&((*pattern==OB)||(*pattern=='*')))||(*str!='\0'))) {
3f4a0c5b
VZ
828 switch (*pattern) {
829 case '\\':
830 pattern++;
831 if (*pattern != '\0')
832 pattern++;
833 break;
834 case '*':
835 pattern++;
836 ret_code = FALSE;
837 while ((*str!='\0')
838 && (!(ret_code=wxMatchWild(pattern, str++, FALSE))))
839 /*loop*/;
840 if (ret_code) {
841 while (*str != '\0')
842 str++;
843 while (*pattern != '\0')
844 pattern++;
845 }
846 break;
847 case '[':
848 pattern++;
849 repeat:
850 if ((*pattern == '\0') || (*pattern == ']')) {
851 done = TRUE;
852 break;
853 }
854 if (*pattern == '\\') {
855 pattern++;
856 if (*pattern == '\0') {
857 done = TRUE;
858 break;
859 }
860 }
861 if (*(pattern + 1) == '-') {
862 c = *pattern;
863 pattern += 2;
864 if (*pattern == ']') {
865 done = TRUE;
866 break;
867 }
868 if (*pattern == '\\') {
869 pattern++;
870 if (*pattern == '\0') {
871 done = TRUE;
872 break;
873 }
874 }
875 if ((*str < c) || (*str > *pattern)) {
876 pattern++;
877 goto repeat;
878 }
879 } else if (*pattern != *str) {
880 pattern++;
881 goto repeat;
882 }
883 pattern++;
884 while ((*pattern != ']') && (*pattern != '\0')) {
885 if ((*pattern == '\\') && (*(pattern + 1) != '\0'))
886 pattern++;
887 pattern++;
888 }
889 if (*pattern != '\0') {
890 pattern++, str++;
891 }
892 break;
893 case '?':
894 pattern++;
895 str++;
896 break;
897 case OB:
898 pattern++;
899 while ((*pattern != CB) && (*pattern != '\0')) {
900 cp = str;
901 ok = TRUE;
902 while (ok && (*cp != '\0') && (*pattern != '\0')
903 && (*pattern != ',') && (*pattern != CB)) {
904 if (*pattern == '\\')
905 pattern++;
906 ok = (*pattern++ == *cp++);
907 }
908 if (*pattern == '\0') {
909 ok = FALSE;
910 done = TRUE;
911 break;
912 } else if (ok) {
913 str = cp;
914 while ((*pattern != CB) && (*pattern != '\0')) {
915 if (*++pattern == '\\') {
916 if (*++pattern == CB)
917 pattern++;
918 }
919 }
920 } else {
921 while (*pattern!=CB && *pattern!=',' && *pattern!='\0') {
922 if (*++pattern == '\\') {
7f555861 923 if (*++pattern == CB || *pattern == ',')
3f4a0c5b
VZ
924 pattern++;
925 }
926 }
927 }
928 if (*pattern != '\0')
929 pattern++;
930 }
931 break;
932 default:
933 if (*str == *pattern) {
934 str++, pattern++;
935 } else {
936 done = TRUE;
937 }
938 }
7f555861
JS
939 }
940 while (*pattern == '*')
3f4a0c5b 941 pattern++;
7f555861
JS
942 return ((*str == '\0') && (*pattern == '\0'));
943};
944
945#endif
946
a0a302dc
JS
947#if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
948
949/*
950When I started programming with Visual C++ v4.0, I missed one of my favorite
951tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
952on MSDN was a step in the right direction, but it is a console application
953and thus has limited features and extensibility. DBWIN32 is my creation
954to solve this problem.
955
b07135ba 956The code is essentially a merging of a stripped down version of the DBWIN code
a0a302dc
JS
957from VC 1.5 and DBMON.C with a few 32 bit changes.
958
b07135ba 959As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
a0a302dc
JS
960built into the operating system and works just by running DBWIN32. The Win95
961team decided not to support this hook, so I have provided code that will do
962this for you. See the file WIN95.TXT for instructions on installing this.
963
964If you have questions, problems or suggestions about DBWIN32, I welcome your
965feedback and plan to actively maintain the code.
966
967Andrew Tucker
968ast@halcyon.com
969
970To download dbwin32, see e.g.:
971
972http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
973*/
974
57c208c5 975#if !defined(__MWERKS__) && !defined(__SALFORDC__) && !defined(__TWIN32__)
a0a302dc 976#include <process.h>
17dff81c 977#endif
a0a302dc
JS
978
979void OutputDebugStringW95(const char* lpOutputString, ...)
980{
981 HANDLE heventDBWIN; /* DBWIN32 synchronization object */
982 HANDLE heventData; /* data passing synch object */
983 HANDLE hSharedFile; /* memory mapped file shared data */
984 LPSTR lpszSharedMem;
985 char achBuffer[500];
986
987 /* create the output buffer */
988 va_list args;
989 va_start(args, lpOutputString);
990 vsprintf(achBuffer, lpOutputString, args);
991 va_end(args);
992
b07135ba
RD
993 /*
994 Do a regular OutputDebugString so that the output is
a0a302dc
JS
995 still seen in the debugger window if it exists.
996
b07135ba 997 This ifdef is necessary to avoid infinite recursion
a0a302dc
JS
998 from the inclusion of W95TRACE.H
999 */
1000#ifdef _UNICODE
1001 ::OutputDebugStringW(achBuffer);
57c208c5
JS
1002#else
1003#ifdef __TWIN32__
1004 ::OutputDebugString(achBuffer);
a0a302dc
JS
1005#else
1006 ::OutputDebugStringA(achBuffer);
57c208c5 1007#endif
a0a302dc
JS
1008#endif
1009
1010 /* bail if it's not Win95 */
1011 {
1012 OSVERSIONINFO VerInfo;
1013 VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
1014 GetVersionEx(&VerInfo);
1015 if ( VerInfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS )
1016 return;
1017 }
1018
1019 /* make sure DBWIN is open and waiting */
1020 heventDBWIN = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_BUFFER_READY");
1021 if ( !heventDBWIN )
1022 {
1023 //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
b07135ba 1024 return;
a0a302dc
JS
1025 }
1026
1027 /* get a handle to the data synch object */
1028 heventData = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_DATA_READY");
1029 if ( !heventData )
1030 {
1031 // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
1032 CloseHandle(heventDBWIN);
b07135ba 1033 return;
a0a302dc 1034 }
b07135ba 1035
a0a302dc 1036 hSharedFile = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0, 4096, "DBWIN_BUFFER");
b07135ba 1037 if (!hSharedFile)
a0a302dc
JS
1038 {
1039 //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
1040 CloseHandle(heventDBWIN);
1041 CloseHandle(heventData);
1042 return;
1043 }
1044
1045 lpszSharedMem = (LPSTR)MapViewOfFile(hSharedFile, FILE_MAP_WRITE, 0, 0, 512);
b07135ba 1046 if (!lpszSharedMem)
a0a302dc
JS
1047 {
1048 //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
1049 CloseHandle(heventDBWIN);
1050 CloseHandle(heventData);
1051 return;
1052 }
1053
1054 /* wait for buffer event */
1055 WaitForSingleObject(heventDBWIN, INFINITE);
1056
1057 /* write it to the shared memory */
ce3ed50d 1058#if defined( __BORLANDC__ ) || defined( __MWERKS__ ) || defined(__SALFORDC__)
a0a302dc
JS
1059 *((LPDWORD)lpszSharedMem) = getpid();
1060#else
1061 *((LPDWORD)lpszSharedMem) = _getpid();
1062#endif
1063
1064 wsprintf(lpszSharedMem + sizeof(DWORD), "%s", achBuffer);
1065
1066 /* signal data ready event */
1067 SetEvent(heventData);
1068
1069 /* clean up handles */
1070 CloseHandle(hSharedFile);
1071 CloseHandle(heventData);
1072 CloseHandle(heventDBWIN);
1073
1074 return;
1075}
1076
1077
1078#endif
1079
c030b70f 1080
cf45d1f4 1081#if 0
c030b70f
JS
1082
1083// maximum mumber of lines the output console should have
1084static const WORD MAX_CONSOLE_LINES = 500;
1085
1086BOOL WINAPI MyConsoleHandler( DWORD dwCtrlType ) { // control signal type
3f4a0c5b
VZ
1087 FreeConsole();
1088 return TRUE;
c030b70f
JS
1089}
1090
1091void wxRedirectIOToConsole()
1092{
1093 int hConHandle;
1094 long lStdHandle;
1095 CONSOLE_SCREEN_BUFFER_INFO coninfo;
1096 FILE *fp;
1097
1098 // allocate a console for this app
1099 AllocConsole();
1100
1101 // set the screen buffer to be big enough to let us scroll text
3f4a0c5b 1102 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
c030b70f
JS
1103 &coninfo);
1104 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
3f4a0c5b 1105 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
c030b70f
JS
1106 coninfo.dwSize);
1107
1108 // redirect unbuffered STDOUT to the console
1109 lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
1110 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
1111 if(hConHandle <= 0) return;
1112 fp = _fdopen( hConHandle, "w" );
1113 *stdout = *fp;
1114 setvbuf( stdout, NULL, _IONBF, 0 );
1115
1116 // redirect unbuffered STDIN to the console
1117 lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
1118 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
1119 if(hConHandle <= 0) return;
1120 fp = _fdopen( hConHandle, "r" );
1121 *stdin = *fp;
1122 setvbuf( stdin, NULL, _IONBF, 0 );
1123
1124 // redirect unbuffered STDERR to the console
1125 lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
1126 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
1127 if(hConHandle <= 0) return;
1128 fp = _fdopen( hConHandle, "w" );
1129 *stderr = *fp;
1130 setvbuf( stderr, NULL, _IONBF, 0 );
3f4a0c5b
VZ
1131
1132 // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
c030b70f
JS
1133 // point to console as well
1134 ios::sync_with_stdio();
1135
3f4a0c5b 1136 SetConsoleCtrlHandler(MyConsoleHandler, TRUE);
c030b70f
JS
1137}
1138#else
1139// Not supported
1140void wxRedirectIOToConsole()
1141{
1142}
1143#endif
1144
1145