Added Win95 implementation of OutputDebugString; added to wxVariant class

(just so Vadim hates it even more :-))


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1084 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart 1998-11-29 21:20:12 +00:00
parent cfbe03c9c3
commit a0a302dcba
9 changed files with 626 additions and 31 deletions

View File

@ -132,3 +132,15 @@ References:
http://agnes.dida.physik.uni-essen.de/~janjaap/mingw32/index.html
- See also http://web.ukonline.co.uk/julian.smart/wxwin/gnuwin32.htm
Notes
-----
- Debugging: under Windows 95, debugging output isn't output in
the same way that it is under NT or Windows 3.1. Set
wxUSE_DBWIN32 to 1 if you wish to enable code to output debugging
info to an external debug monitor, such as Andrew Tucker's DBWIN32.
You can download DBWIN32 from:
http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
and it's also on the wxWindows CD-ROM.

View File

@ -185,3 +185,6 @@ Perhaps rewrite wxFile to use FILE* descriptors, so Eof and Flush
can work.
Find out how to set wxFileSelector position.
Maybe bundle Andrew Tucker's DBWIN32 with wxWindows (it's only
26KB), for viewing debug messages without a debugger.

View File

@ -162,5 +162,14 @@ inline bool wxStyleHasBorder(long style)
#define WS_EX_CLIENTEDGE 0
#endif
#if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
#ifdef OutputDebugString
#undef OutputDebugString
#endif
#define OutputDebugString OutputDebugStringW95
extern void OutputDebugStringW95(const char*, ...);
#endif
#endif
// _WX_PRIVATE_H_

View File

@ -195,6 +195,9 @@
#define wxUSE_NATIVE_STATUSBAR 1
// Set to 0 to use cross-platform wxStatusBar
#define wxUSE_DBWIN32 1
// Use Andrew Tucker's OutputDebugString implementation
// (required on Win95 only). See utils.cpp.
/*
* Any platform

View File

@ -21,6 +21,11 @@
#include "wx/string.h"
#include "wx/list.h"
#if wxUSE_TIMEDATE
#include "wx/time.h"
#include "wx/date.h"
#endif
#if wxUSE_IOSTREAMH
#include <iostream.h>
#else
@ -79,18 +84,21 @@ public:
// Construction & destruction
wxVariant();
wxVariant(double val);
wxVariant(long val);
wxVariant(bool val);
wxVariant(char val);
wxVariant(const wxString& val);
wxVariant(const char* val); // Necessary or VC++ assumes bool!
/* Causes ambiguity
wxVariant(const wxStringList& val);
*/
wxVariant(const wxList& val); // List of variants
wxVariant(double val, const wxString& name = wxEmptyString);
wxVariant(long val, const wxString& name = wxEmptyString);
wxVariant(bool val, const wxString& name = wxEmptyString);
wxVariant(char val, const wxString& name = wxEmptyString);
wxVariant(const wxString& val, const wxString& name = wxEmptyString);
wxVariant(const char* val, const wxString& name = wxEmptyString); // Necessary or VC++ assumes bool!
wxVariant(const wxStringList& val, const wxString& name = wxEmptyString);
wxVariant(const wxList& val, const wxString& name = wxEmptyString); // List of variants
#if wxUSE_TIMEDATE
wxVariant(const wxTime& val, const wxString& name = wxEmptyString); // Time
wxVariant(const wxDate& val, const wxString& name = wxEmptyString); // Date
#endif
wxVariant(void* ptr, const wxString& name = wxEmptyString); // void* (general purpose)
wxVariant(wxVariantData* data, const wxString& name = wxEmptyString); // User-defined data
wxVariant(const wxVariant& variant);
wxVariant(wxVariantData* data); // User-defined data
~wxVariant();
// Generic operators
@ -126,6 +134,17 @@ public:
bool operator== (const wxList& value) const;
bool operator!= (const wxList& value) const;
void operator= (const wxList& value) ;
#if wxUSE_TIMEDATE
bool operator== (const wxTime& value) const;
bool operator!= (const wxTime& value) const;
void operator= (const wxTime& value) ;
bool operator== (const wxDate& value) const;
bool operator!= (const wxDate& value) const;
void operator= (const wxDate& value) ;
#endif
bool operator== (void* value) const;
bool operator!= (void* value) const;
void operator= (void* value) ;
// Treat a list variant as an array
wxVariant operator[] (size_t idx) const;
@ -137,10 +156,20 @@ public:
// Other implicit conversions
inline operator double () const { return GetDouble(); }
inline operator char () const { return GetChar(); }
inline operator long () const { return GetLong(); }
inline operator bool () const { return GetBool(); }
#if wxUSE_TIMEDATE
inline operator wxTime () const { return GetTime(); }
inline operator wxDate () const { return GetDate(); }
#endif
inline operator void* () const { return GetVoidPtr(); }
// Accessors
// Sets/gets name
inline void SetName(const wxString& name) { m_name = name; }
inline const wxString& GetName() const { return m_name; }
// Tests whether there is data
inline bool IsNull() const { return (m_data == (wxVariantData*) NULL); }
@ -166,6 +195,11 @@ public:
wxString GetString() const ;
wxList& GetList() const ;
wxStringList& GetStringList() const ;
#if wxUSE_TIMEDATE
wxTime GetTime() const ;
wxDate GetDate() const ;
#endif
void* GetVoidPtr() const ;
// Operations
// Make NULL (i.e. delete the data)
@ -189,17 +223,26 @@ public:
// Clear list
void ClearList();
// Implementation
protected:
// Type conversion
bool Convert(long* value) const;
bool Convert(bool* value) const;
bool Convert(double* value) const;
bool Convert(wxString* value) const;
bool Convert(char* value) const;
#if wxUSE_TIMEDATE
bool Convert(wxTime* value) const;
bool Convert(wxDate* value) const;
#endif
// Attributes
protected:
wxVariantData* m_data;
wxString m_name;
};
extern wxVariant wxNullVariant;
#endif
// _WX_VARIANT_H_

View File

@ -52,6 +52,8 @@
#ifdef __WXMSW__
#include <windows.h>
// Redefines OutputDebugString if necessary
#include "wx/msw/private.h"
#else //Unix
#include <signal.h>
#endif //Win/Unix

View File

@ -142,7 +142,7 @@ bool wxVariantDataList::Write(ostream& str) const
{
wxString s;
Write(s);
str << s;
str << (const char*) s;
return TRUE;
}
@ -243,7 +243,7 @@ bool wxVariantDataStringList::Write(ostream& str) const
{
wxString s;
Write(s);
str << s;
str << (const char*) s;
return TRUE;
}
@ -329,7 +329,7 @@ bool wxVariantDataLong::Write(ostream& str) const
{
wxString s;
Write(s);
str << s;
str << (const char*) s;
return TRUE;
}
@ -415,7 +415,7 @@ bool wxVariantDataReal::Write(ostream& str) const
{
wxString s;
Write(s);
str << s;
str << (const char*) s;
return TRUE;
}
@ -501,7 +501,7 @@ bool wxVariantDataBool::Write(ostream& str) const
{
wxString s;
Write(s);
str << s;
str << (const char*) s;
return TRUE;
}
@ -588,7 +588,7 @@ bool wxVariantDataChar::Write(ostream& str) const
{
wxString s;
Write(s);
str << s;
str << (const char*) s;
return TRUE;
}
@ -671,7 +671,7 @@ bool wxVariantDataString::Eq(wxVariantData& data) const
bool wxVariantDataString::Write(ostream& str) const
{
str << m_value;
str << (const char*) m_value;
return TRUE;
}
@ -707,6 +707,233 @@ bool wxVariantDataString::Read(wxString& str)
IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData)
/*
* wxVariantDataTime
*/
#if wxUSE_TIMEDATE
class wxVariantDataTime: public wxVariantData
{
DECLARE_DYNAMIC_CLASS(wxVariantDataTime)
public:
wxVariantDataTime() { }
wxVariantDataTime(const wxTime& value) { m_value = value; }
inline wxTime GetValue() const { return m_value; }
inline void SetValue(const wxTime& value) { m_value = value; }
virtual void Copy(wxVariantData& data);
virtual bool Eq(wxVariantData& data) const;
virtual bool Write(ostream& str) const;
virtual bool Write(wxString& str) const;
virtual bool Read(istream& str);
virtual bool Read(wxString& str);
virtual wxString GetType() const { return "time"; };
virtual wxVariantData* Clone() { return new wxVariantDataTime; }
protected:
wxTime m_value;
};
IMPLEMENT_DYNAMIC_CLASS(wxVariantDataTime, wxVariantData)
void wxVariantDataTime::Copy(wxVariantData& data)
{
wxASSERT_MSG( (data.GetType() == "time"), "wxVariantDataTime::Copy: Can't copy to this type of data" );
wxVariantDataTime& otherData = (wxVariantDataTime&) data;
otherData.m_value = m_value;
}
bool wxVariantDataTime::Eq(wxVariantData& data) const
{
wxASSERT_MSG( (data.GetType() == "time"), "wxVariantDataTime::Eq: argument mismatch" );
wxVariantDataTime& otherData = (wxVariantDataTime&) data;
return (otherData.m_value == m_value);
}
bool wxVariantDataTime::Write(ostream& str) const
{
wxString s;
Write(s);
str << (const char*) s;
return TRUE;
}
bool wxVariantDataTime::Write(wxString& str) const
{
char*s = m_value.FormatTime();
str = s;
return TRUE;
}
bool wxVariantDataTime::Read(istream& str)
{
// Not implemented
return FALSE;
}
bool wxVariantDataTime::Read(wxString& str)
{
// Not implemented
return FALSE;
}
/*
* wxVariantDataDate
*/
class wxVariantDataDate: public wxVariantData
{
DECLARE_DYNAMIC_CLASS(wxVariantDataDate)
public:
wxVariantDataDate() { }
wxVariantDataDate(const wxDate& value) { m_value = value; }
inline wxDate GetValue() const { return m_value; }
inline void SetValue(const wxDate& value) { m_value = value; }
virtual void Copy(wxVariantData& data);
virtual bool Eq(wxVariantData& data) const;
virtual bool Write(ostream& str) const;
virtual bool Write(wxString& str) const;
virtual bool Read(istream& str);
virtual bool Read(wxString& str);
virtual wxString GetType() const { return "date"; };
virtual wxVariantData* Clone() { return new wxVariantDataDate; }
protected:
wxDate m_value;
};
IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDate, wxVariantData)
void wxVariantDataDate::Copy(wxVariantData& data)
{
wxASSERT_MSG( (data.GetType() == "date"), "wxVariantDataDate::Copy: Can't copy to this type of data" );
wxVariantDataDate& otherData = (wxVariantDataDate&) data;
otherData.m_value = m_value;
}
bool wxVariantDataDate::Eq(wxVariantData& data) const
{
wxASSERT_MSG( (data.GetType() == "date"), "wxVariantDataDate::Eq: argument mismatch" );
wxVariantDataDate& otherData = (wxVariantDataDate&) data;
return (otherData.m_value == m_value);
}
bool wxVariantDataDate::Write(ostream& str) const
{
wxString s;
Write(s);
str << (const char*) s;
return TRUE;
}
bool wxVariantDataDate::Write(wxString& str) const
{
str = m_value.FormatDate();
return TRUE;
}
bool wxVariantDataDate::Read(istream& str)
{
// Not implemented
return FALSE;
}
bool wxVariantDataDate::Read(wxString& str)
{
// Not implemented
return FALSE;
}
#endif
// wxUSE_TIMEDATE
/*
* wxVariantDataVoidPtr
*/
class wxVariantDataVoidPtr: public wxVariantData
{
DECLARE_DYNAMIC_CLASS(wxVariantDataVoidPtr)
public:
wxVariantDataVoidPtr() { }
wxVariantDataVoidPtr(void* value) { m_value = value; }
inline void* GetValue() const { return m_value; }
inline void SetValue(void* value) { m_value = value; }
virtual void Copy(wxVariantData& data);
virtual bool Eq(wxVariantData& data) const;
virtual bool Write(ostream& str) const;
virtual bool Write(wxString& str) const;
virtual bool Read(istream& str);
virtual bool Read(wxString& str);
virtual wxString GetType() const { return "void*"; };
virtual wxVariantData* Clone() { return new wxVariantDataVoidPtr; }
protected:
void* m_value;
};
IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr, wxVariantData)
void wxVariantDataVoidPtr::Copy(wxVariantData& data)
{
wxASSERT_MSG( (data.GetType() == "void*"), "wxVariantDataVoidPtr::Copy: Can't copy to this type of data" );
wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
otherData.m_value = m_value;
}
bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
{
wxASSERT_MSG( (data.GetType() == "void*"), "wxVariantDataVoidPtr::Eq: argument mismatch" );
wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
return (otherData.m_value == m_value);
}
bool wxVariantDataVoidPtr::Write(ostream& str) const
{
wxString s;
Write(s);
str << (const char*) s;
return TRUE;
}
bool wxVariantDataVoidPtr::Write(wxString& str) const
{
char buf[80];
sprintf(buf, "%ld", (long) m_value);
str = buf;
return TRUE;
}
bool wxVariantDataVoidPtr::Read(istream& str)
{
// Not implemented
return FALSE;
}
bool wxVariantDataVoidPtr::Read(wxString& str)
{
// Not implemented
return FALSE;
}
/*
* wxVariant
*/
@ -717,48 +944,75 @@ IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
wxVariant::wxVariant()
{
m_data = (wxVariantData*) NULL;
m_name = wxEmptyString;
}
wxVariant::wxVariant(double val)
wxVariant::wxVariant(double val, const wxString& name)
{
m_data = new wxVariantDataReal(val);
m_name = name;
}
wxVariant::wxVariant(long val)
wxVariant::wxVariant(long val, const wxString& name)
{
m_data = new wxVariantDataLong(val);
m_name = name;
}
wxVariant::wxVariant(bool val)
wxVariant::wxVariant(bool val, const wxString& name)
{
m_data = new wxVariantDataBool(val);
m_name = name;
}
wxVariant::wxVariant(char val)
wxVariant::wxVariant(char val, const wxString& name)
{
m_data = new wxVariantDataChar(val);
m_name = name;
}
wxVariant::wxVariant(const wxString& val)
wxVariant::wxVariant(const wxString& val, const wxString& name)
{
m_data = new wxVariantDataString(val);
m_name = name;
}
wxVariant::wxVariant(const char* val)
wxVariant::wxVariant(const char* val, const wxString& name)
{
m_data = new wxVariantDataString(wxString(val));
m_name = name;
}
/* Causes ambiguity
wxVariant::wxVariant(const wxStringList& val)
wxVariant::wxVariant(const wxStringList& val, const wxString& name)
{
m_data = new wxVariantDataStringList(val);
m_name = name;
}
*/
wxVariant::wxVariant(const wxList& val) // List of variants
wxVariant::wxVariant(const wxList& val, const wxString& name) // List of variants
{
m_data = new wxVariantDataList(val);
m_name = name;
}
#if wxUSE_TIMEDATE
wxVariant::wxVariant(const wxTime& val, const wxString& name) // Time
{
m_data = new wxVariantDataTime(val);
m_name = name;
}
wxVariant::wxVariant(const wxDate& val, const wxString& name) // Date
{
m_data = new wxVariantDataDate(val);
m_name = name;
}
#endif
wxVariant::wxVariant(void* val, const wxString& name) // Void ptr
{
m_data = new wxVariantDataVoidPtr(val);
m_name = name;
}
wxVariant::wxVariant(const wxVariant& variant)
@ -770,11 +1024,13 @@ wxVariant::wxVariant(const wxVariant& variant)
}
else
m_data = (wxVariantData*) NULL;
m_name = variant.m_name;
}
wxVariant::wxVariant(wxVariantData* data) // User-defined data
wxVariant::wxVariant(wxVariantData* data, const wxString& name) // User-defined data
{
m_data = data;
m_name = name;
}
wxVariant::~wxVariant()
@ -1041,6 +1297,87 @@ void wxVariant::operator= (const wxList& value)
}
}
#if wxUSE_TIMEDATE
bool wxVariant::operator== (const wxTime& value) const
{
wxTime thisValue;
if (!Convert(&thisValue))
return FALSE;
else
return (value == thisValue);
}
bool wxVariant::operator!= (const wxTime& value) const
{
return (!((*this) == value));
}
void wxVariant::operator= (const wxTime& value)
{
if (GetType() == "time")
{
((wxVariantDataTime*)GetData())->SetValue(value);
}
else
{
if (m_data)
delete m_data;
m_data = new wxVariantDataTime(value);
}
}
bool wxVariant::operator== (const wxDate& value) const
{
wxDate thisValue;
if (!Convert(&thisValue))
return FALSE;
else
return (value == thisValue);
}
bool wxVariant::operator!= (const wxDate& value) const
{
return (!((*this) == value));
}
void wxVariant::operator= (const wxDate& value)
{
if (GetType() == "date")
{
((wxVariantDataTime*)GetData())->SetValue(value);
}
else
{
if (m_data)
delete m_data;
m_data = new wxVariantDataDate(value);
}
}
#endif
bool wxVariant::operator== (void* value) const
{
return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
}
bool wxVariant::operator!= (void* value) const
{
return (!((*this) == value));
}
void wxVariant::operator= (void* value)
{
if (GetType() == "void*")
{
((wxVariantDataVoidPtr*)GetData())->SetValue(value);
}
else
{
if (m_data)
delete m_data;
m_data = new wxVariantDataVoidPtr(value);
}
}
// Treat a list variant as an array
wxVariant wxVariant::operator[] (size_t idx) const
@ -1193,6 +1530,39 @@ wxString wxVariant::GetString() const
}
}
#if wxUSE_TIMEDATE
wxTime wxVariant::GetTime() const
{
wxTime value;
if (Convert(& value))
return value;
else
{
wxFAIL_MSG("Could not convert to a time");
return wxTime();
}
}
wxDate wxVariant::GetDate() const
{
wxDate value;
if (Convert(& value))
return value;
else
{
wxFAIL_MSG("Could not convert to a date");
return wxDate();
}
}
#endif
void* wxVariant::GetVoidPtr() const
{
wxASSERT( (GetType() == "void*") );
return (void*) ((wxVariantDataVoidPtr*) m_data)->GetValue();
}
wxList& wxVariant::GetList() const
{
wxASSERT( (GetType() == "list") );
@ -1352,3 +1722,29 @@ bool wxVariant::Convert(wxString* value) const
return TRUE;
}
#if wxUSE_TIMEDATE
bool wxVariant::Convert(wxTime* value) const
{
wxString type(GetType());
if (type == "time")
*value = ((wxVariantDataTime*)GetData())->GetValue();
else if (type == "date")
*value = wxTime(((wxVariantDataDate*)GetData())->GetValue());
else
return FALSE;
return TRUE;
}
bool wxVariant::Convert(wxDate* value) const
{
wxString type(GetType());
if (type == "date")
*value = ((wxVariantDataDate*)GetData())->GetValue();
else
return FALSE;
return TRUE;
}
#endif
// wxUSE_TIMEDATE

View File

@ -124,8 +124,8 @@ wxPaintDC::~wxPaintDC()
if ( !--ms_PaintCount ) {
::EndPaint((HWND)m_canvas->GetHWND(), &g_paintStruct);
m_hDCCount--;
m_hDC = NULL;
ms_PaintHDC = NULL;
m_hDC = (WXHDC) NULL;
ms_PaintHDC = (WXHDC) NULL;
}
else { }//: ms_PaintHDC still in use
}

View File

@ -894,3 +894,130 @@ bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
#endif
#if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
/*
When I started programming with Visual C++ v4.0, I missed one of my favorite
tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
on MSDN was a step in the right direction, but it is a console application
and thus has limited features and extensibility. DBWIN32 is my creation
to solve this problem.
The code is essentially a merging of a stripped down version of the DBWIN code
from VC 1.5 and DBMON.C with a few 32 bit changes.
As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
built into the operating system and works just by running DBWIN32. The Win95
team decided not to support this hook, so I have provided code that will do
this for you. See the file WIN95.TXT for instructions on installing this.
If you have questions, problems or suggestions about DBWIN32, I welcome your
feedback and plan to actively maintain the code.
Andrew Tucker
ast@halcyon.com
To download dbwin32, see e.g.:
http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
*/
#include <process.h>
void OutputDebugStringW95(const char* lpOutputString, ...)
{
HANDLE heventDBWIN; /* DBWIN32 synchronization object */
HANDLE heventData; /* data passing synch object */
HANDLE hSharedFile; /* memory mapped file shared data */
LPSTR lpszSharedMem;
char achBuffer[500];
/* create the output buffer */
va_list args;
va_start(args, lpOutputString);
vsprintf(achBuffer, lpOutputString, args);
va_end(args);
/*
Do a regular OutputDebugString so that the output is
still seen in the debugger window if it exists.
This ifdef is necessary to avoid infinite recursion
from the inclusion of W95TRACE.H
*/
#ifdef _UNICODE
::OutputDebugStringW(achBuffer);
#else
::OutputDebugStringA(achBuffer);
#endif
/* bail if it's not Win95 */
{
OSVERSIONINFO VerInfo;
VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&VerInfo);
if ( VerInfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS )
return;
}
/* make sure DBWIN is open and waiting */
heventDBWIN = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_BUFFER_READY");
if ( !heventDBWIN )
{
//MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
return;
}
/* get a handle to the data synch object */
heventData = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_DATA_READY");
if ( !heventData )
{
// MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
CloseHandle(heventDBWIN);
return;
}
hSharedFile = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0, 4096, "DBWIN_BUFFER");
if (!hSharedFile)
{
//MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
CloseHandle(heventDBWIN);
CloseHandle(heventData);
return;
}
lpszSharedMem = (LPSTR)MapViewOfFile(hSharedFile, FILE_MAP_WRITE, 0, 0, 512);
if (!lpszSharedMem)
{
//MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
CloseHandle(heventDBWIN);
CloseHandle(heventData);
return;
}
/* wait for buffer event */
WaitForSingleObject(heventDBWIN, INFINITE);
/* write it to the shared memory */
#ifdef __BORLANDC__
*((LPDWORD)lpszSharedMem) = getpid();
#else
*((LPDWORD)lpszSharedMem) = _getpid();
#endif
wsprintf(lpszSharedMem + sizeof(DWORD), "%s", achBuffer);
/* signal data ready event */
SetEvent(heventData);
/* clean up handles */
CloseHandle(hSharedFile);
CloseHandle(heventData);
CloseHandle(heventDBWIN);
return;
}
#endif