1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Various utilities
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 // #pragma implementation "utils.h" // Note: this is done in utilscmn.cpp now.
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
27 #include "wx/cursor.h"
30 #include "wx/msw/private.h"
41 #include <sys/unistd.h>
47 #ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
48 // this (3.1 I believe) and how to test for it.
49 // If this works for Borland 4.0 as well, then no worries.
65 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
71 // In the WIN.INI file
72 static const char WX_SECTION
[] = "wxWindows";
73 static const char eHOSTNAME
[] = "HostName";
74 static const char eUSERID
[] = "UserId";
75 static const char eUSERNAME
[] = "UserName";
77 // For the following functions we SHOULD fill in support
78 // for Windows-NT (which I don't know) as I assume it begin
79 // a POSIX Unix (so claims MS) that it has some special
80 // functions beyond those provided by WinSock
82 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
83 bool wxGetHostName(char *buf
, int maxSize
)
86 DWORD nSize
= maxSize
;
87 return (::GetComputerName(buf
, &nSize
) != 0);
90 const char *default_host
= "noname";
92 if ((sysname
= getenv("SYSTEM_NAME")) == NULL
) {
93 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
95 strncpy(buf
, sysname
, maxSize
- 1);
97 return *buf
? TRUE
: FALSE
;
101 // Get user ID e.g. jacs
102 bool wxGetUserId(char *buf
, int maxSize
)
104 #if defined(__WIN32__) && !defined(__win32s__) && 0
105 // Gets the current user's full name according to the MS article PSS ID
107 // Seems to be the same as the login name for me?
108 char *UserName
= new char[256];
109 char *Domain
= new char[256];
110 DWORD maxCharacters
= 255;
111 GetUserName( UserName
, &maxCharacters
);
112 GetComputerName( Domain
, &maxCharacters
);
114 WCHAR wszUserName
[256]; // Unicode user name
115 WCHAR wszDomain
[256];
118 struct _SERVER_INFO_100
*si100
; // Server structure
119 struct _USER_INFO_2
*ui
; // User structure
121 // Convert ASCII user name and domain to Unicode.
123 MultiByteToWideChar( CP_ACP
, 0, UserName
,
124 strlen(UserName
)+1, wszUserName
, sizeof(wszUserName
) );
125 MultiByteToWideChar( CP_ACP
, 0, Domain
,
126 strlen(Domain
)+1, wszDomain
, sizeof(wszDomain
) );
128 // Get the computer name of a DC for the specified domain.
129 // >If you get a link error on this, include netapi32.lib<
131 NetGetDCName( NULL
, wszDomain
, &ComputerName
);
133 // Look up the user on the DC.
135 if(NetUserGetInfo( (LPWSTR
) ComputerName
,
136 (LPWSTR
) &wszUserName
, 2, (LPBYTE
*) &ui
))
138 printf( "Error getting user information.\n" );
142 // Convert the Unicode full name to ASCII.
144 WideCharToMultiByte( CP_ACP
, 0, ui
->usri2_full_name
,
145 -1, buf
, 256, NULL
, NULL
);
149 DWORD nSize = maxSize;
150 return ::GetUserName(buf, &nSize);
154 const char *default_id
= "anonymous";
156 // Can't assume we have NIS (PC-NFS) or some other ID daemon
158 if ( (user
= getenv("USER")) == NULL
&&
159 (user
= getenv("LOGNAME")) == NULL
) {
160 // Use wxWindows configuration data (comming soon)
161 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
163 strncpy(buf
, user
, maxSize
- 1);
164 return *buf
? TRUE
: FALSE
;
168 // Get user name e.g. Julian Smart
169 bool wxGetUserName(char *buf
, int maxSize
)
171 const char *default_name
= "Unknown User";
172 #if defined(__WIN32__)
174 DWORD nSize = maxSize;
175 In VC++ 4.0, results in unresolved symbol __imp__GetUserNameA
176 if (GetUserName(buf, &nSize))
180 // Could use NIS, MS-Mail or other site specific programs
181 // Use wxWindows configuration data
182 GetProfileString(WX_SECTION
, eUSERNAME
, default_name
, buf
, maxSize
- 1);
183 return *buf
? TRUE
: FALSE
;
186 #if !defined(__WATCOMC__) && !defined(__GNUWIN32__) && wxUSE_PENWINDOWS
187 extern HANDLE g_hPenWin
; // PenWindows Running?
190 // PenWindows Does have a user concept!
191 // Get the current owner of the recognizer
192 GetPrivateProfileString("Current", "User", default_name
, wxBuffer
, maxSize
- 1, "PENWIN.INI");
193 strncpy(buf
, wxBuffer
, maxSize
- 1);
198 // Could use NIS, MS-Mail or other site specific programs
199 // Use wxWindows configuration data
200 GetProfileString(WX_SECTION
, eUSERNAME
, default_name
, buf
, maxSize
- 1);
202 return *buf
? TRUE
: FALSE
;
206 int wxKill(long pid
, int sig
)
212 // Execute a program in an Interactive Shell
215 wxShell(const wxString
& command
)
218 if ((shell
= getenv("COMSPEC")) == NULL
)
219 shell
= "\\COMMAND.COM";
223 sprintf(tmp
, "%s /c %s", shell
, WXSTRINGCAST command
);
227 return (wxExecute((char *)tmp
, FALSE
) != 0);
230 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
231 long wxGetFreeMemory(void)
233 #if defined(__WIN32__) && !defined(__BORLANDC__)
234 MEMORYSTATUS memStatus
;
235 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
236 GlobalMemoryStatus(&memStatus
);
237 return memStatus
.dwAvailPhys
;
239 return (long)GetFreeSpace(0);
243 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
244 static bool inTimer
= FALSE
;
245 class wxSleepTimer
: public wxTimer
248 inline void Notify(void)
255 static wxTimer
*wxTheSleepTimer
= NULL
;
257 void wxSleep(int nSecs
)
259 #if 0 // WIN32 hangs app
265 wxTheSleepTimer
= new wxSleepTimer
;
267 wxTheSleepTimer
->Start(nSecs
*1000);
270 if (wxTheApp
->Pending())
271 wxTheApp
->Dispatch();
273 delete wxTheSleepTimer
;
274 wxTheSleepTimer
= NULL
;
278 // Consume all events until no more left
279 void wxFlushEvents(void)
284 // Output a debug mess., in a system dependent fashion.
285 void wxDebugMsg(const char *fmt
...)
288 static char buffer
[512];
290 if (!wxTheApp
->GetWantDebugOutput())
295 wvsprintf(buffer
,fmt
,ap
) ;
296 OutputDebugString((LPCSTR
)buffer
) ;
301 // Non-fatal error: pop up message box and (possibly) continue
302 void wxError(const wxString
& msg
, const wxString
& title
)
304 sprintf(wxBuffer
, "%s\nContinue?", WXSTRINGCAST msg
);
305 if (MessageBox(NULL
, (LPCSTR
)wxBuffer
, (LPCSTR
)WXSTRINGCAST title
,
306 MB_ICONSTOP
| MB_YESNO
) == IDNO
)
310 // Fatal error: pop up message box and abort
311 void wxFatalError(const wxString
& msg
, const wxString
& title
)
313 sprintf(wxBuffer
, "%s: %s", WXSTRINGCAST title
, WXSTRINGCAST msg
);
314 FatalAppExit(0, (LPCSTR
)wxBuffer
);
320 // Removed by RD because IHMO syncronous sound is a Bad Thing. MessageBeep
321 // will do a similar thing anyway if there is no sound card...
323 // Beep(1000,1000) ; // 1kHz during 1 sec.
329 // Chris Breeze 27/5/98: revised WIN32 code to
330 // detect WindowsNT correctly
331 int wxGetOsVersion(int *majorVsn
, int *minorVsn
)
333 extern char *wxOsVersion
;
334 if (majorVsn
) *majorVsn
= 0;
335 if (minorVsn
) *minorVsn
= 0;
339 memset(&info
, 0, sizeof(OSVERSIONINFO
));
340 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
341 if (GetVersionEx(&info
))
343 if (majorVsn
) *majorVsn
= info
.dwMajorVersion
;
344 if (minorVsn
) *minorVsn
= info
.dwMinorVersion
;
345 switch (info
.dwPlatformId
)
347 case VER_PLATFORM_WIN32s
:
350 case VER_PLATFORM_WIN32_WINDOWS
:
353 case VER_PLATFORM_WIN32_NT
:
358 return wxWINDOWS
; // error if we get here, return generic value
362 # ifdef __WINDOWS_386__
365 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
366 extern HANDLE g_hPenWin
;
367 retValue
= g_hPenWin
? wxPENWINDOWS
: wxWINDOWS
;
370 // @@@@ To be completed. I don't have the manual here...
371 if (majorVsn
) *majorVsn
= 3 ;
372 if (minorVsn
) *minorVsn
= 1 ;
377 // Reading and writing resources (eg WIN.INI, .Xdefaults)
379 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
)
382 return (WritePrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)value
, (LPCSTR
)WXSTRINGCAST file
) != 0);
384 return (WriteProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)WXSTRINGCAST value
) != 0);
387 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
)
390 sprintf(buf
, "%.4f", value
);
391 return wxWriteResource(section
, entry
, buf
, file
);
394 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
)
397 sprintf(buf
, "%ld", value
);
398 return wxWriteResource(section
, entry
, buf
, file
);
401 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
)
404 sprintf(buf
, "%d", value
);
405 return wxWriteResource(section
, entry
, buf
, file
);
408 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
)
410 static const char defunkt
[] = "$$default";
413 int n
= GetPrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
414 (LPSTR
)wxBuffer
, 1000, (LPCSTR
)WXSTRINGCAST file
);
415 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
420 int n
= GetProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
421 (LPSTR
)wxBuffer
, 1000);
422 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
425 if (*value
) delete[] (*value
);
426 *value
= copystring(wxBuffer
);
430 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
)
433 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
436 *value
= (float)strtod(s
, NULL
);
443 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
)
446 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
449 *value
= strtol(s
, NULL
, 10);
456 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
)
459 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
462 *value
= (int)strtol(s
, NULL
, 10);
468 #endif // wxUSE_RESOURCES
471 static HCURSOR wxBusyCursorOld
= 0;
472 static int wxBusyCursorCount
= 0;
474 // Set the cursor to the busy cursor for all windows
475 void wxBeginBusyCursor(wxCursor
*cursor
)
477 wxBusyCursorCount
++;
478 if (wxBusyCursorCount
== 1)
480 wxBusyCursorOld
= ::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
484 (void)::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
488 // Restore cursor to normal
489 void wxEndBusyCursor(void)
491 if (wxBusyCursorCount
== 0)
494 wxBusyCursorCount
--;
495 if (wxBusyCursorCount
== 0)
497 ::SetCursor(wxBusyCursorOld
);
502 // TRUE if we're between the above two calls
505 return (wxBusyCursorCount
> 0);
508 const char* wxGetHomeDir(wxString
*pstr
)
510 wxString
& strDir
= *pstr
;
513 const char *szHome
= getenv("HOME");
514 if ( szHome
== NULL
) {
516 wxLogWarning(_("can't find user's HOME, using current directory."));
522 // add a trailing slash if needed
523 if ( strDir
.Last() != '/' )
527 const char *szHome
= getenv("HOMEDRIVE");
528 if ( szHome
!= NULL
)
530 szHome
= getenv("HOMEPATH");
531 if ( szHome
!= NULL
) {
534 // the idea is that under NT these variables have default values
535 // of "%systemdrive%:" and "\\". As we don't want to create our
536 // config files in the root directory of the system drive, we will
537 // create it in our program's dir. However, if the user took care
538 // to set HOMEPATH to something other than "\\", we suppose that he
539 // knows what he is doing and use the supplied value.
540 if ( strcmp(szHome
, "\\") != 0 )
541 return strDir
.c_str();
545 // Win16 has no idea about home, so use the working directory instead
548 // 260 was taken from windef.h
554 ::GetModuleFileName(::GetModuleHandle(NULL
),
555 strPath
.GetWriteBuf(MAX_PATH
), MAX_PATH
);
556 strPath
.UngetWriteBuf();
558 // extract the dir name
559 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
563 return strDir
.c_str();
567 char *wxGetUserHome (const wxString
& user
)
570 wxString
user1(user
);
574 if (wxGetUserId(tmp
, sizeof(tmp
)/sizeof(char))) {
575 // Guests belong in the temp dir
576 if (Stricmp(tmp
, "annonymous") == 0) {
577 if ((home
= getenv("TMP")) != NULL
||
578 (home
= getenv("TMPDIR")) != NULL
||
579 (home
= getenv("TEMP")) != NULL
)
580 return *home
? home
: "\\";
582 if (Stricmp(tmp
, WXSTRINGCAST user1
) == 0)
587 if ((home
= getenv("HOME")) != NULL
)
589 strcpy(wxBuffer
, home
);
590 Unix2DosFilename(wxBuffer
);
593 return NULL
; // No home known!
596 // Check whether this window wants to process messages, e.g. Stop button
597 // in long calculations.
598 bool wxCheckForInterrupt(wxWindow
*wnd
)
602 HWND win
= (HWND
) wnd
->GetHWND();
603 while(PeekMessage(&msg
,win
,0,0,PM_REMOVE
)){
604 TranslateMessage(&msg
);
605 DispatchMessage(&msg
);
607 return TRUE
;//*** temporary?
610 wxError("wnd==NULL !!!");
611 return FALSE
;//*** temporary?
615 // MSW only: get user-defined resource from the .res file.
616 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
619 char *wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
)
623 HRSRC hResource
= ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
626 HRSRC hResource
= ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
628 HRSRC hResource
= ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
634 HGLOBAL hData
= ::LoadResource(wxGetInstance(), hResource
);
637 char *theText
= (char *)LockResource(hData
);
641 s
= copystring(theText
);
645 UnlockResource(hData
);
649 // GlobalFree(hData);
655 void wxGetMousePosition( int* x
, int* y
)
658 GetCursorPos( & pt
);
663 // Return TRUE if we have a colour display
664 bool wxColourDisplay(void)
666 HDC dc
= ::GetDC(NULL
);
668 int noCols
= GetDeviceCaps(dc
, NUMCOLORS
);
669 if ((noCols
== -1) || (noCols
> 2))
677 // Returns depth of screen
678 int wxDisplayDepth(void)
680 HDC dc
= ::GetDC(NULL
);
681 int planes
= GetDeviceCaps(dc
, PLANES
);
682 int bitsPerPixel
= GetDeviceCaps(dc
, BITSPIXEL
);
683 int depth
= planes
*bitsPerPixel
;
688 // Get size of display
689 void wxDisplaySize(int *width
, int *height
)
691 HDC dc
= ::GetDC(NULL
);
692 *width
= GetDeviceCaps(dc
, HORZRES
); *height
= GetDeviceCaps(dc
, VERTRES
);
696 bool wxDirExists(const wxString
& dir
)
698 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
699 #if defined(__WIN32__)
700 WIN32_FIND_DATA fileInfo
;
703 struct ffblk fileInfo
;
705 struct find_t fileInfo
;
709 #if defined(__WIN32__)
710 HANDLE h
= FindFirstFile((LPTSTR
) WXSTRINGCAST dir
,(LPWIN32_FIND_DATA
)&fileInfo
);
712 if (h
==INVALID_HANDLE_VALUE
)
716 return ((fileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) == FILE_ATTRIBUTE_DIRECTORY
);
719 // In Borland findfirst has a different argument
720 // ordering from _dos_findfirst. But _dos_findfirst
721 // _should_ be ok in both MS and Borland... why not?
723 return ((findfirst(WXSTRINGCAST dir
, &fileInfo
, _A_SUBDIR
) == 0 && (fileInfo
.ff_attrib
& _A_SUBDIR
) != 0));
725 return (((_dos_findfirst(WXSTRINGCAST dir
, _A_SUBDIR
, &fileInfo
) == 0) && (fileInfo
.attrib
& _A_SUBDIR
)) != 0);
730 wxString WXDLLEXPORT
wxGetWindowText(WXHWND hWnd
)
733 int len
= GetWindowTextLength((HWND
)hWnd
) + 1;
734 GetWindowText((HWND
)hWnd
, str
.GetWriteBuf(len
), len
);
741 //------------------------------------------------------------------------
742 // wild character routines
743 //------------------------------------------------------------------------
745 bool wxIsWild( const wxString
& pattern
)
747 wxString tmp
= pattern
;
748 char *pat
= WXSTRINGCAST(tmp
);
751 case '?': case '*': case '[': case '{':
762 bool wxMatchWild( const wxString
& pat
, const wxString
& text
, bool dot_special
)
765 char *pattern
= WXSTRINGCAST(tmp1
);
766 wxString tmp2
= text
;
767 char *str
= WXSTRINGCAST(tmp2
);
770 bool done
= FALSE
, ret_code
, ok
;
771 // Below is for vi fans
772 const char OB
= '{', CB
= '}';
774 // dot_special means '.' only matches '.'
775 if (dot_special
&& *str
== '.' && *pattern
!= *str
)
778 while ((*pattern
!= '\0') && (!done
)
779 && (((*str
=='\0')&&((*pattern
==OB
)||(*pattern
=='*')))||(*str
!='\0'))) {
783 if (*pattern
!= '\0')
790 && (!(ret_code
=wxMatchWild(pattern
, str
++, FALSE
))))
795 while (*pattern
!= '\0')
802 if ((*pattern
== '\0') || (*pattern
== ']')) {
806 if (*pattern
== '\\') {
808 if (*pattern
== '\0') {
813 if (*(pattern
+ 1) == '-') {
816 if (*pattern
== ']') {
820 if (*pattern
== '\\') {
822 if (*pattern
== '\0') {
827 if ((*str
< c
) || (*str
> *pattern
)) {
831 } else if (*pattern
!= *str
) {
836 while ((*pattern
!= ']') && (*pattern
!= '\0')) {
837 if ((*pattern
== '\\') && (*(pattern
+ 1) != '\0'))
841 if (*pattern
!= '\0') {
851 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
854 while (ok
&& (*cp
!= '\0') && (*pattern
!= '\0')
855 && (*pattern
!= ',') && (*pattern
!= CB
)) {
856 if (*pattern
== '\\')
858 ok
= (*pattern
++ == *cp
++);
860 if (*pattern
== '\0') {
866 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
867 if (*++pattern
== '\\') {
868 if (*++pattern
== CB
)
873 while (*pattern
!=CB
&& *pattern
!=',' && *pattern
!='\0') {
874 if (*++pattern
== '\\') {
875 if (*++pattern
== CB
|| *pattern
== ',')
880 if (*pattern
!= '\0')
885 if (*str
== *pattern
) {
892 while (*pattern
== '*')
894 return ((*str
== '\0') && (*pattern
== '\0'));
899 #if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
902 When I started programming with Visual C++ v4.0, I missed one of my favorite
903 tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
904 on MSDN was a step in the right direction, but it is a console application
905 and thus has limited features and extensibility. DBWIN32 is my creation
906 to solve this problem.
908 The code is essentially a merging of a stripped down version of the DBWIN code
909 from VC 1.5 and DBMON.C with a few 32 bit changes.
911 As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
912 built into the operating system and works just by running DBWIN32. The Win95
913 team decided not to support this hook, so I have provided code that will do
914 this for you. See the file WIN95.TXT for instructions on installing this.
916 If you have questions, problems or suggestions about DBWIN32, I welcome your
917 feedback and plan to actively maintain the code.
922 To download dbwin32, see e.g.:
924 http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
929 void OutputDebugStringW95(const char* lpOutputString
, ...)
931 HANDLE heventDBWIN
; /* DBWIN32 synchronization object */
932 HANDLE heventData
; /* data passing synch object */
933 HANDLE hSharedFile
; /* memory mapped file shared data */
937 /* create the output buffer */
939 va_start(args
, lpOutputString
);
940 vsprintf(achBuffer
, lpOutputString
, args
);
944 Do a regular OutputDebugString so that the output is
945 still seen in the debugger window if it exists.
947 This ifdef is necessary to avoid infinite recursion
948 from the inclusion of W95TRACE.H
951 ::OutputDebugStringW(achBuffer
);
953 ::OutputDebugStringA(achBuffer
);
956 /* bail if it's not Win95 */
958 OSVERSIONINFO VerInfo
;
959 VerInfo
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
960 GetVersionEx(&VerInfo
);
961 if ( VerInfo
.dwPlatformId
!= VER_PLATFORM_WIN32_WINDOWS
)
965 /* make sure DBWIN is open and waiting */
966 heventDBWIN
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_BUFFER_READY");
969 //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
973 /* get a handle to the data synch object */
974 heventData
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_DATA_READY");
977 // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
978 CloseHandle(heventDBWIN
);
982 hSharedFile
= CreateFileMapping((HANDLE
)-1, NULL
, PAGE_READWRITE
, 0, 4096, "DBWIN_BUFFER");
985 //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
986 CloseHandle(heventDBWIN
);
987 CloseHandle(heventData
);
991 lpszSharedMem
= (LPSTR
)MapViewOfFile(hSharedFile
, FILE_MAP_WRITE
, 0, 0, 512);
994 //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
995 CloseHandle(heventDBWIN
);
996 CloseHandle(heventData
);
1000 /* wait for buffer event */
1001 WaitForSingleObject(heventDBWIN
, INFINITE
);
1003 /* write it to the shared memory */
1005 *((LPDWORD
)lpszSharedMem
) = getpid();
1007 *((LPDWORD
)lpszSharedMem
) = _getpid();
1010 wsprintf(lpszSharedMem
+ sizeof(DWORD
), "%s", achBuffer
);
1012 /* signal data ready event */
1013 SetEvent(heventData
);
1015 /* clean up handles */
1016 CloseHandle(hSharedFile
);
1017 CloseHandle(heventData
);
1018 CloseHandle(heventDBWIN
);