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