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
);
321 Beep(1000,1000) ; // 1kHz during 1 sec.
327 // Chris Breeze 27/5/98: revised WIN32 code to
328 // detect WindowsNT correctly
329 int wxGetOsVersion(int *majorVsn
, int *minorVsn
)
331 extern char *wxOsVersion
;
332 if (majorVsn
) *majorVsn
= 0;
333 if (minorVsn
) *minorVsn
= 0;
337 memset(&info
, 0, sizeof(OSVERSIONINFO
));
338 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
339 if (GetVersionEx(&info
))
341 if (majorVsn
) *majorVsn
= info
.dwMajorVersion
;
342 if (minorVsn
) *minorVsn
= info
.dwMinorVersion
;
343 switch (info
.dwPlatformId
)
345 case VER_PLATFORM_WIN32s
:
348 case VER_PLATFORM_WIN32_WINDOWS
:
351 case VER_PLATFORM_WIN32_NT
:
356 return wxWINDOWS
; // error if we get here, return generic value
360 # ifdef __WINDOWS_386__
363 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
364 extern HANDLE g_hPenWin
;
365 retValue
= g_hPenWin
? wxPENWINDOWS
: wxWINDOWS
;
368 // @@@@ To be completed. I don't have the manual here...
369 if (majorVsn
) *majorVsn
= 3 ;
370 if (minorVsn
) *minorVsn
= 1 ;
375 // Reading and writing resources (eg WIN.INI, .Xdefaults)
377 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
)
380 return (WritePrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)value
, (LPCSTR
)WXSTRINGCAST file
) != 0);
382 return (WriteProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)WXSTRINGCAST value
) != 0);
385 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
)
388 sprintf(buf
, "%.4f", value
);
389 return wxWriteResource(section
, entry
, buf
, file
);
392 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
)
395 sprintf(buf
, "%ld", value
);
396 return wxWriteResource(section
, entry
, buf
, file
);
399 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
)
402 sprintf(buf
, "%d", value
);
403 return wxWriteResource(section
, entry
, buf
, file
);
406 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
)
408 static const char defunkt
[] = "$$default";
411 int n
= GetPrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
412 (LPSTR
)wxBuffer
, 1000, (LPCSTR
)WXSTRINGCAST file
);
413 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
418 int n
= GetProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
419 (LPSTR
)wxBuffer
, 1000);
420 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
423 if (*value
) delete[] (*value
);
424 *value
= copystring(wxBuffer
);
428 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
)
431 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
434 *value
= (float)strtod(s
, NULL
);
441 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
)
444 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
447 *value
= strtol(s
, NULL
, 10);
454 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
)
457 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
460 *value
= (int)strtol(s
, NULL
, 10);
466 #endif // wxUSE_RESOURCES
469 static HCURSOR wxBusyCursorOld
= 0;
470 static int wxBusyCursorCount
= 0;
472 // Set the cursor to the busy cursor for all windows
473 void wxBeginBusyCursor(wxCursor
*cursor
)
475 wxBusyCursorCount
++;
476 if (wxBusyCursorCount
== 1)
478 wxBusyCursorOld
= ::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
482 (void)::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
486 // Restore cursor to normal
487 void wxEndBusyCursor(void)
489 if (wxBusyCursorCount
== 0)
492 wxBusyCursorCount
--;
493 if (wxBusyCursorCount
== 0)
495 ::SetCursor(wxBusyCursorOld
);
500 // TRUE if we're between the above two calls
503 return (wxBusyCursorCount
> 0);
506 const char* wxGetHomeDir(wxString
*pstr
)
508 wxString
& strDir
= *pstr
;
511 const char *szHome
= getenv("HOME");
512 if ( szHome
== NULL
) {
514 wxLogWarning(_("can't find user's HOME, using current directory."));
520 // add a trailing slash if needed
521 if ( strDir
.Last() != '/' )
525 const char *szHome
= getenv("HOMEDRIVE");
526 if ( szHome
!= NULL
)
528 szHome
= getenv("HOMEPATH");
529 if ( szHome
!= NULL
) {
532 // the idea is that under NT these variables have default values
533 // of "%systemdrive%:" and "\\". As we don't want to create our
534 // config files in the root directory of the system drive, we will
535 // create it in our program's dir. However, if the user took care
536 // to set HOMEPATH to something other than "\\", we suppose that he
537 // knows what he is doing and use the supplied value.
538 if ( strcmp(szHome
, "\\") != 0 )
539 return strDir
.c_str();
543 // Win16 has no idea about home, so use the working directory instead
546 // 260 was taken from windef.h
552 ::GetModuleFileName(::GetModuleHandle(NULL
),
553 strPath
.GetWriteBuf(MAX_PATH
), MAX_PATH
);
554 strPath
.UngetWriteBuf();
556 // extract the dir name
557 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
561 return strDir
.c_str();
565 char *wxGetUserHome (const wxString
& user
)
568 wxString
user1(user
);
572 if (wxGetUserId(tmp
, sizeof(tmp
)/sizeof(char))) {
573 // Guests belong in the temp dir
574 if (Stricmp(tmp
, "annonymous") == 0) {
575 if ((home
= getenv("TMP")) != NULL
||
576 (home
= getenv("TMPDIR")) != NULL
||
577 (home
= getenv("TEMP")) != NULL
)
578 return *home
? home
: "\\";
580 if (Stricmp(tmp
, WXSTRINGCAST user1
) == 0)
585 if ((home
= getenv("HOME")) != NULL
)
587 strcpy(wxBuffer
, home
);
588 Unix2DosFilename(wxBuffer
);
591 return NULL
; // No home known!
594 // Check whether this window wants to process messages, e.g. Stop button
595 // in long calculations.
596 bool wxCheckForInterrupt(wxWindow
*wnd
)
600 HWND win
= (HWND
) wnd
->GetHWND();
601 while(PeekMessage(&msg
,win
,0,0,PM_REMOVE
)){
602 TranslateMessage(&msg
);
603 DispatchMessage(&msg
);
605 return TRUE
;//*** temporary?
608 wxError("wnd==NULL !!!");
609 return FALSE
;//*** temporary?
613 // MSW only: get user-defined resource from the .res file.
614 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
617 char *wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
)
621 HRSRC hResource
= ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
624 HRSRC hResource
= ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
626 HRSRC hResource
= ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
632 HGLOBAL hData
= ::LoadResource(wxGetInstance(), hResource
);
635 char *theText
= (char *)LockResource(hData
);
639 s
= copystring(theText
);
643 UnlockResource(hData
);
647 // GlobalFree(hData);
653 void wxGetMousePosition( int* x
, int* y
)
656 GetCursorPos( & pt
);
661 // Return TRUE if we have a colour display
662 bool wxColourDisplay(void)
664 HDC dc
= ::GetDC(NULL
);
666 int noCols
= GetDeviceCaps(dc
, NUMCOLORS
);
667 if ((noCols
== -1) || (noCols
> 2))
675 // Returns depth of screen
676 int wxDisplayDepth(void)
678 HDC dc
= ::GetDC(NULL
);
679 int planes
= GetDeviceCaps(dc
, PLANES
);
680 int bitsPerPixel
= GetDeviceCaps(dc
, BITSPIXEL
);
681 int depth
= planes
*bitsPerPixel
;
686 // Get size of display
687 void wxDisplaySize(int *width
, int *height
)
689 HDC dc
= ::GetDC(NULL
);
690 *width
= GetDeviceCaps(dc
, HORZRES
); *height
= GetDeviceCaps(dc
, VERTRES
);
694 bool wxDirExists(const wxString
& dir
)
696 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
697 #if defined(__WIN32__)
698 WIN32_FIND_DATA fileInfo
;
701 struct ffblk fileInfo
;
703 struct find_t fileInfo
;
707 #if defined(__WIN32__)
708 HANDLE h
= FindFirstFile((LPTSTR
) WXSTRINGCAST dir
,(LPWIN32_FIND_DATA
)&fileInfo
);
710 if (h
==INVALID_HANDLE_VALUE
)
714 return ((fileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) == FILE_ATTRIBUTE_DIRECTORY
);
717 // In Borland findfirst has a different argument
718 // ordering from _dos_findfirst. But _dos_findfirst
719 // _should_ be ok in both MS and Borland... why not?
721 return ((findfirst(WXSTRINGCAST dir
, &fileInfo
, _A_SUBDIR
) == 0 && (fileInfo
.ff_attrib
& _A_SUBDIR
) != 0));
723 return (((_dos_findfirst(WXSTRINGCAST dir
, _A_SUBDIR
, &fileInfo
) == 0) && (fileInfo
.attrib
& _A_SUBDIR
)) != 0);
728 wxString WXDLLEXPORT
wxGetWindowText(WXHWND hWnd
)
731 int len
= GetWindowTextLength((HWND
)hWnd
) + 1;
732 GetWindowText((HWND
)hWnd
, str
.GetWriteBuf(len
), len
);
739 //------------------------------------------------------------------------
740 // wild character routines
741 //------------------------------------------------------------------------
743 bool wxIsWild( const wxString
& pattern
)
745 wxString tmp
= pattern
;
746 char *pat
= WXSTRINGCAST(tmp
);
749 case '?': case '*': case '[': case '{':
760 bool wxMatchWild( const wxString
& pat
, const wxString
& text
, bool dot_special
)
763 char *pattern
= WXSTRINGCAST(tmp1
);
764 wxString tmp2
= text
;
765 char *str
= WXSTRINGCAST(tmp2
);
768 bool done
= FALSE
, ret_code
, ok
;
769 // Below is for vi fans
770 const char OB
= '{', CB
= '}';
772 // dot_special means '.' only matches '.'
773 if (dot_special
&& *str
== '.' && *pattern
!= *str
)
776 while ((*pattern
!= '\0') && (!done
)
777 && (((*str
=='\0')&&((*pattern
==OB
)||(*pattern
=='*')))||(*str
!='\0'))) {
781 if (*pattern
!= '\0')
788 && (!(ret_code
=wxMatchWild(pattern
, str
++, FALSE
))))
793 while (*pattern
!= '\0')
800 if ((*pattern
== '\0') || (*pattern
== ']')) {
804 if (*pattern
== '\\') {
806 if (*pattern
== '\0') {
811 if (*(pattern
+ 1) == '-') {
814 if (*pattern
== ']') {
818 if (*pattern
== '\\') {
820 if (*pattern
== '\0') {
825 if ((*str
< c
) || (*str
> *pattern
)) {
829 } else if (*pattern
!= *str
) {
834 while ((*pattern
!= ']') && (*pattern
!= '\0')) {
835 if ((*pattern
== '\\') && (*(pattern
+ 1) != '\0'))
839 if (*pattern
!= '\0') {
849 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
852 while (ok
&& (*cp
!= '\0') && (*pattern
!= '\0')
853 && (*pattern
!= ',') && (*pattern
!= CB
)) {
854 if (*pattern
== '\\')
856 ok
= (*pattern
++ == *cp
++);
858 if (*pattern
== '\0') {
864 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
865 if (*++pattern
== '\\') {
866 if (*++pattern
== CB
)
871 while (*pattern
!=CB
&& *pattern
!=',' && *pattern
!='\0') {
872 if (*++pattern
== '\\') {
873 if (*++pattern
== CB
|| *pattern
== ',')
878 if (*pattern
!= '\0')
883 if (*str
== *pattern
) {
890 while (*pattern
== '*')
892 return ((*str
== '\0') && (*pattern
== '\0'));
897 #if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
900 When I started programming with Visual C++ v4.0, I missed one of my favorite
901 tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
902 on MSDN was a step in the right direction, but it is a console application
903 and thus has limited features and extensibility. DBWIN32 is my creation
904 to solve this problem.
906 The code is essentially a merging of a stripped down version of the DBWIN code
907 from VC 1.5 and DBMON.C with a few 32 bit changes.
909 As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
910 built into the operating system and works just by running DBWIN32. The Win95
911 team decided not to support this hook, so I have provided code that will do
912 this for you. See the file WIN95.TXT for instructions on installing this.
914 If you have questions, problems or suggestions about DBWIN32, I welcome your
915 feedback and plan to actively maintain the code.
920 To download dbwin32, see e.g.:
922 http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
927 void OutputDebugStringW95(const char* lpOutputString
, ...)
929 HANDLE heventDBWIN
; /* DBWIN32 synchronization object */
930 HANDLE heventData
; /* data passing synch object */
931 HANDLE hSharedFile
; /* memory mapped file shared data */
935 /* create the output buffer */
937 va_start(args
, lpOutputString
);
938 vsprintf(achBuffer
, lpOutputString
, args
);
942 Do a regular OutputDebugString so that the output is
943 still seen in the debugger window if it exists.
945 This ifdef is necessary to avoid infinite recursion
946 from the inclusion of W95TRACE.H
949 ::OutputDebugStringW(achBuffer
);
951 ::OutputDebugStringA(achBuffer
);
954 /* bail if it's not Win95 */
956 OSVERSIONINFO VerInfo
;
957 VerInfo
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
958 GetVersionEx(&VerInfo
);
959 if ( VerInfo
.dwPlatformId
!= VER_PLATFORM_WIN32_WINDOWS
)
963 /* make sure DBWIN is open and waiting */
964 heventDBWIN
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_BUFFER_READY");
967 //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
971 /* get a handle to the data synch object */
972 heventData
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_DATA_READY");
975 // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
976 CloseHandle(heventDBWIN
);
980 hSharedFile
= CreateFileMapping((HANDLE
)-1, NULL
, PAGE_READWRITE
, 0, 4096, "DBWIN_BUFFER");
983 //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
984 CloseHandle(heventDBWIN
);
985 CloseHandle(heventData
);
989 lpszSharedMem
= (LPSTR
)MapViewOfFile(hSharedFile
, FILE_MAP_WRITE
, 0, 0, 512);
992 //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
993 CloseHandle(heventDBWIN
);
994 CloseHandle(heventData
);
998 /* wait for buffer event */
999 WaitForSingleObject(heventDBWIN
, INFINITE
);
1001 /* write it to the shared memory */
1003 *((LPDWORD
)lpszSharedMem
) = getpid();
1005 *((LPDWORD
)lpszSharedMem
) = _getpid();
1008 wsprintf(lpszSharedMem
+ sizeof(DWORD
), "%s", achBuffer
);
1010 /* signal data ready event */
1011 SetEvent(heventData
);
1013 /* clean up handles */
1014 CloseHandle(hSharedFile
);
1015 CloseHandle(heventData
);
1016 CloseHandle(heventDBWIN
);