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