A patch adding wxHTMLDataObject which can be used for handling the standard platform formats for transfering HTML formatted text.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@71610 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -334,6 +334,45 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
#endif // wxUSE_UNICODE
|
#endif // wxUSE_UNICODE
|
||||||
|
|
||||||
|
class WXDLLIMPEXP_CORE wxHTMLDataObject : public wxDataObjectSimple
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// ctor: you can specify the text here or in SetText(), or override
|
||||||
|
// GetText()
|
||||||
|
wxHTMLDataObject(const wxString& html = wxEmptyString)
|
||||||
|
: wxDataObjectSimple(wxDF_HTML),
|
||||||
|
m_html(html)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual functions which you may override if you want to provide text on
|
||||||
|
// demand only - otherwise, the trivial default versions will be used
|
||||||
|
virtual size_t GetLength() const { return m_html.Len() + 1; }
|
||||||
|
virtual wxString GetHTML() const { return m_html; }
|
||||||
|
virtual void SetHTML(const wxString& html) { m_html = html; }
|
||||||
|
|
||||||
|
virtual size_t GetDataSize() const;
|
||||||
|
virtual bool GetDataHere(void *buf) const;
|
||||||
|
virtual bool SetData(size_t len, const void *buf);
|
||||||
|
|
||||||
|
// Must provide overloads to avoid hiding them (and warnings about it)
|
||||||
|
virtual size_t GetDataSize(const wxDataFormat&) const
|
||||||
|
{
|
||||||
|
return GetDataSize();
|
||||||
|
}
|
||||||
|
virtual bool GetDataHere(const wxDataFormat&, void *buf) const
|
||||||
|
{
|
||||||
|
return GetDataHere(buf);
|
||||||
|
}
|
||||||
|
virtual bool SetData(const wxDataFormat&, size_t len, const void *buf)
|
||||||
|
{
|
||||||
|
return SetData(len, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxString m_html;
|
||||||
|
};
|
||||||
|
|
||||||
class WXDLLIMPEXP_CORE wxTextDataObject : public wxDataObjectSimple
|
class WXDLLIMPEXP_CORE wxTextDataObject : public wxDataObjectSimple
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@@ -34,9 +34,7 @@
|
|||||||
@itemdef{wxDF_FILENAME,
|
@itemdef{wxDF_FILENAME,
|
||||||
A list of filenames.}
|
A list of filenames.}
|
||||||
@itemdef{wxDF_HTML,
|
@itemdef{wxDF_HTML,
|
||||||
An HTML string. This is only valid when passed to
|
An HTML string. This is currently only valid on Mac and MSW.}
|
||||||
wxSetClipboardData when compiled with Visual C++ in non-Unicode
|
|
||||||
mode.}
|
|
||||||
@endDefList
|
@endDefList
|
||||||
|
|
||||||
As mentioned above, these standard formats may be passed to any function
|
As mentioned above, these standard formats may be passed to any function
|
||||||
@@ -789,4 +787,31 @@ public:
|
|||||||
const wxArrayString& GetFilenames() const;
|
const wxArrayString& GetFilenames() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class wxHTMLDataObject
|
||||||
|
|
||||||
|
wxHTMLDataObject is used for working with HTML-formatted text.
|
||||||
|
|
||||||
|
@library{wxcore}
|
||||||
|
@category{dnd}
|
||||||
|
|
||||||
|
@see wxDataObject, wxDataObjectSimple
|
||||||
|
*/
|
||||||
|
class wxHTMLDataObject : public wxDataObjectSimple
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Constructor.
|
||||||
|
*/
|
||||||
|
wxHTMLDataObject(const wxString& html = wxEmptyString);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the HTML string.
|
||||||
|
*/
|
||||||
|
virtual wxString GetHTML() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets the HTML string.
|
||||||
|
*/
|
||||||
|
virtual void SetHTML(const wxString& html);
|
||||||
|
};
|
||||||
|
@@ -427,6 +427,117 @@ bool wxTextDataObject::SetData(size_t len, const void *buf)
|
|||||||
|
|
||||||
#endif // different wxTextDataObject implementations
|
#endif // different wxTextDataObject implementations
|
||||||
|
|
||||||
|
size_t wxHTMLDataObject::GetDataSize() const
|
||||||
|
{
|
||||||
|
size_t size = 0;
|
||||||
|
// Windows and Mac always use UTF-8, and docs suggest GTK does as well.
|
||||||
|
wxCharBuffer buffer = wxConvUTF8.cWX2MB( GetHTML().c_str() );
|
||||||
|
|
||||||
|
if (buffer)
|
||||||
|
{
|
||||||
|
size = strlen( buffer );
|
||||||
|
#if __WXMSW__
|
||||||
|
// On Windows we need to add some stuff to the string to satisfy
|
||||||
|
// its clipboard format requirements.
|
||||||
|
size += 400;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxHTMLDataObject::GetDataHere(void *buf) const
|
||||||
|
{
|
||||||
|
if ( !buf )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Windows and Mac always use UTF-8, and docs suggest GTK does as well.
|
||||||
|
wxCharBuffer html = wxConvUTF8.cWX2MB( GetHTML().c_str() );
|
||||||
|
if ( !html )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
size_t bytes = GetDataSize();
|
||||||
|
#if __WXMSW__
|
||||||
|
// add the extra info that the MSW clipboard format requires.
|
||||||
|
char* buffer = new char[bytes];
|
||||||
|
|
||||||
|
// Create a template string for the HTML header...
|
||||||
|
strcpy(buffer,
|
||||||
|
"Version:0.9\r\n"
|
||||||
|
"StartHTML:00000000\r\n"
|
||||||
|
"EndHTML:00000000\r\n"
|
||||||
|
"StartFragment:00000000\r\n"
|
||||||
|
"EndFragment:00000000\r\n"
|
||||||
|
"<html><body>\r\n"
|
||||||
|
"<!--StartFragment -->\r\n");
|
||||||
|
|
||||||
|
// Append the HTML...
|
||||||
|
strcat(buffer, html);
|
||||||
|
strcat(buffer, "\r\n");
|
||||||
|
// Finish up the HTML format...
|
||||||
|
strcat(buffer,
|
||||||
|
"<!--EndFragment-->\r\n"
|
||||||
|
"</body>\r\n"
|
||||||
|
"</html>");
|
||||||
|
|
||||||
|
// Now go back, calculate all the lengths, and write out the
|
||||||
|
// necessary header information. Note, wsprintf() truncates the
|
||||||
|
// string when you overwrite it so you follow up with code to replace
|
||||||
|
// the 0 appended at the end with a '\r'...
|
||||||
|
char *ptr = strstr(buffer, "StartHTML");
|
||||||
|
sprintf(ptr+10, "%08u", (unsigned)(strstr(buffer, "<html>") - buffer));
|
||||||
|
*(ptr+10+8) = '\r';
|
||||||
|
|
||||||
|
ptr = strstr(buffer, "EndHTML");
|
||||||
|
sprintf(ptr+8, "%08u", (unsigned)strlen(buffer));
|
||||||
|
*(ptr+8+8) = '\r';
|
||||||
|
|
||||||
|
ptr = strstr(buffer, "StartFragment");
|
||||||
|
sprintf(ptr+14, "%08u", (unsigned)(strstr(buffer, "<!--StartFrag") - buffer));
|
||||||
|
*(ptr+14+8) = '\r';
|
||||||
|
|
||||||
|
ptr = strstr(buffer, "EndFragment");
|
||||||
|
sprintf(ptr+12, "%08u", (unsigned)(strstr(buffer, "<!--EndFrag") - buffer));
|
||||||
|
*(ptr+12+8) = '\r';
|
||||||
|
#else
|
||||||
|
wxCharBuffer buffer = html;
|
||||||
|
#endif // __WXMSW__
|
||||||
|
|
||||||
|
memcpy( (char*) buf, buffer, bytes );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxHTMLDataObject::SetData(size_t WXUNUSED(len), const void *buf)
|
||||||
|
{
|
||||||
|
if ( buf == NULL )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Windows and Mac always use UTF-8, and docs suggest GTK does as well.
|
||||||
|
wxWCharBuffer buffer = wxConvUTF8.cMB2WX( (const char*)buf );
|
||||||
|
|
||||||
|
wxString html(buffer);
|
||||||
|
// To be consistent with other platforms, we only add the Fragment part
|
||||||
|
// of the Windows HTML clipboard format to the data object.
|
||||||
|
#if __WXMSW__
|
||||||
|
int fragmentStart = html.rfind("StartFragment");
|
||||||
|
int fragmentEnd = html.rfind("EndFragment");
|
||||||
|
|
||||||
|
if (fragmentStart != wxNOT_FOUND && fragmentEnd != wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
int startCommentEnd = html.find("-->", fragmentStart) + 3;
|
||||||
|
int endCommentStart = html.rfind("<!--", fragmentEnd);
|
||||||
|
|
||||||
|
if (startCommentEnd != wxNOT_FOUND && endCommentStart != wxNOT_FOUND)
|
||||||
|
html = html.Mid(startCommentEnd, endCommentStart - startCommentEnd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
SetHTML( html );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxCustomDataObject
|
// wxCustomDataObject
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -33,6 +33,7 @@ GdkAtom g_textAtom = 0;
|
|||||||
GdkAtom g_altTextAtom = 0;
|
GdkAtom g_altTextAtom = 0;
|
||||||
GdkAtom g_pngAtom = 0;
|
GdkAtom g_pngAtom = 0;
|
||||||
GdkAtom g_fileAtom = 0;
|
GdkAtom g_fileAtom = 0;
|
||||||
|
GdkAtom g_htmlAtom = 0;
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// wxDataFormat
|
// wxDataFormat
|
||||||
@@ -95,6 +96,9 @@ void wxDataFormat::SetType( wxDataFormatId type )
|
|||||||
if (m_type == wxDF_FILENAME)
|
if (m_type == wxDF_FILENAME)
|
||||||
m_format = g_fileAtom;
|
m_format = g_fileAtom;
|
||||||
else
|
else
|
||||||
|
if (m_type == wxDF_HTML)
|
||||||
|
m_format = g_htmlAtom;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
wxFAIL_MSG( wxT("invalid dataformat") );
|
wxFAIL_MSG( wxT("invalid dataformat") );
|
||||||
}
|
}
|
||||||
@@ -131,6 +135,9 @@ void wxDataFormat::SetId( NativeFormat format )
|
|||||||
else
|
else
|
||||||
if (m_format == g_fileAtom)
|
if (m_format == g_fileAtom)
|
||||||
m_type = wxDF_FILENAME;
|
m_type = wxDF_FILENAME;
|
||||||
|
else
|
||||||
|
if (m_format == g_htmlAtom)
|
||||||
|
m_type = wxDF_HTML;
|
||||||
else
|
else
|
||||||
m_type = wxDF_PRIVATE;
|
m_type = wxDF_PRIVATE;
|
||||||
}
|
}
|
||||||
@@ -164,6 +171,8 @@ void wxDataFormat::PrepareFormats()
|
|||||||
g_pngAtom = gdk_atom_intern( "image/png", FALSE );
|
g_pngAtom = gdk_atom_intern( "image/png", FALSE );
|
||||||
if (!g_fileAtom)
|
if (!g_fileAtom)
|
||||||
g_fileAtom = gdk_atom_intern( "text/uri-list", FALSE );
|
g_fileAtom = gdk_atom_intern( "text/uri-list", FALSE );
|
||||||
|
if (!g_htmlAtom)
|
||||||
|
g_htmlAtom = gdk_atom_intern( "text/html", FALSE );
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
@@ -79,6 +79,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
static bool gs_wxClipboardIsOpen = false;
|
static bool gs_wxClipboardIsOpen = false;
|
||||||
|
static int gs_htmlcfid = 0;
|
||||||
|
|
||||||
bool wxOpenClipboard()
|
bool wxOpenClipboard()
|
||||||
{
|
{
|
||||||
@@ -139,7 +140,9 @@ bool wxIsClipboardOpened()
|
|||||||
|
|
||||||
bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
|
bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
|
||||||
{
|
{
|
||||||
wxDataFormat::NativeFormat cf = dataFormat.GetFormatId();
|
wxDataFormat::NativeFormat cf = dataFormat.GetFormatId();
|
||||||
|
if (cf == wxDF_HTML)
|
||||||
|
cf = gs_htmlcfid;
|
||||||
|
|
||||||
if ( ::IsClipboardFormatAvailable(cf) )
|
if ( ::IsClipboardFormatAvailable(cf) )
|
||||||
{
|
{
|
||||||
@@ -304,10 +307,6 @@ bool wxSetClipboardData(wxDataFormat dataFormat,
|
|||||||
char *buf = new char [400 + strlen(html)];
|
char *buf = new char [400 + strlen(html)];
|
||||||
if(!buf) return false;
|
if(!buf) return false;
|
||||||
|
|
||||||
// Get clipboard id for HTML format...
|
|
||||||
static int cfid = 0;
|
|
||||||
if(!cfid) cfid = RegisterClipboardFormat(wxT("HTML Format"));
|
|
||||||
|
|
||||||
// Create a template string for the HTML header...
|
// Create a template string for the HTML header...
|
||||||
strcpy(buf,
|
strcpy(buf,
|
||||||
"Version:0.9\r\n"
|
"Version:0.9\r\n"
|
||||||
@@ -358,7 +357,7 @@ bool wxSetClipboardData(wxDataFormat dataFormat,
|
|||||||
strcpy(ptr, buf);
|
strcpy(ptr, buf);
|
||||||
GlobalUnlock(hText);
|
GlobalUnlock(hText);
|
||||||
|
|
||||||
handle = ::SetClipboardData(cfid, hText);
|
handle = ::SetClipboardData(gs_htmlcfid, hText);
|
||||||
|
|
||||||
// Free memory...
|
// Free memory...
|
||||||
GlobalFree(hText);
|
GlobalFree(hText);
|
||||||
@@ -598,6 +597,10 @@ bool wxClipboard::Flush()
|
|||||||
|
|
||||||
bool wxClipboard::Open()
|
bool wxClipboard::Open()
|
||||||
{
|
{
|
||||||
|
// Get clipboard id for HTML format...
|
||||||
|
if(!gs_htmlcfid)
|
||||||
|
gs_htmlcfid = RegisterClipboardFormat(wxT("HTML Format"));
|
||||||
|
|
||||||
// OLE opens clipboard for us
|
// OLE opens clipboard for us
|
||||||
m_isOpened = true;
|
m_isOpened = true;
|
||||||
#if wxUSE_OLE_CLIPBOARD
|
#if wxUSE_OLE_CLIPBOARD
|
||||||
@@ -814,6 +817,8 @@ bool wxClipboard::GetData( wxDataObject& data )
|
|||||||
// convert to NativeFormat Id
|
// convert to NativeFormat Id
|
||||||
cf = formats[n].GetFormatId();
|
cf = formats[n].GetFormatId();
|
||||||
|
|
||||||
|
if (cf == wxDF_HTML)
|
||||||
|
cf = gs_htmlcfid;
|
||||||
// if the format is not available, try the next one
|
// if the format is not available, try the next one
|
||||||
// this test includes implicit / sythetic formats
|
// this test includes implicit / sythetic formats
|
||||||
if ( !::IsClipboardFormatAvailable(cf) )
|
if ( !::IsClipboardFormatAvailable(cf) )
|
||||||
|
@@ -67,6 +67,21 @@
|
|||||||
#define GetTymedName(tymed) wxEmptyString
|
#define GetTymedName(tymed) wxEmptyString
|
||||||
#endif // wxDEBUG_LEVEL/!wxDEBUG_LEVEL
|
#endif // wxDEBUG_LEVEL/!wxDEBUG_LEVEL
|
||||||
|
|
||||||
|
wxDataFormat HtmlFormatFixup(wxDataFormat format)
|
||||||
|
{
|
||||||
|
// Since the HTML format is dynamically registered, the wxDF_HTML
|
||||||
|
// format does not match the native constant in the way other formats do,
|
||||||
|
// so for the format checks below to work, we must change the native
|
||||||
|
// id to the wxDF_HTML constant.
|
||||||
|
wxChar s_szBuf[256];
|
||||||
|
if (::GetClipboardFormatName(format, s_szBuf, WXSIZEOF(s_szBuf)))
|
||||||
|
{
|
||||||
|
if (s_szBuf == wxString("HTML Format"))
|
||||||
|
format = wxDF_HTML;
|
||||||
|
}
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxIEnumFORMATETC interface implementation
|
// wxIEnumFORMATETC interface implementation
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -183,7 +198,10 @@ wxIEnumFORMATETC::wxIEnumFORMATETC(const wxDataFormat *formats, ULONG nCount)
|
|||||||
m_nCount = nCount;
|
m_nCount = nCount;
|
||||||
m_formats = new CLIPFORMAT[nCount];
|
m_formats = new CLIPFORMAT[nCount];
|
||||||
for ( ULONG n = 0; n < nCount; n++ ) {
|
for ( ULONG n = 0; n < nCount; n++ ) {
|
||||||
m_formats[n] = formats[n].GetFormatId();
|
if (formats[n].GetFormatId() != wxDF_HTML)
|
||||||
|
m_formats[n] = formats[n].GetFormatId();
|
||||||
|
else
|
||||||
|
m_formats[n] = ::RegisterClipboardFormat(wxT("HTML Format"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,6 +308,7 @@ STDMETHODIMP wxIDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
|
|||||||
// for the bitmaps and metafiles we use the handles instead of global memory
|
// for the bitmaps and metafiles we use the handles instead of global memory
|
||||||
// to pass the data
|
// to pass the data
|
||||||
wxDataFormat format = (wxDataFormat::NativeFormat)pformatetcIn->cfFormat;
|
wxDataFormat format = (wxDataFormat::NativeFormat)pformatetcIn->cfFormat;
|
||||||
|
format = HtmlFormatFixup(format);
|
||||||
|
|
||||||
switch ( format )
|
switch ( format )
|
||||||
{
|
{
|
||||||
@@ -432,6 +451,8 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
|
|||||||
{
|
{
|
||||||
wxDataFormat format = pformatetc->cfFormat;
|
wxDataFormat format = pformatetc->cfFormat;
|
||||||
|
|
||||||
|
format = HtmlFormatFixup(format);
|
||||||
|
|
||||||
// this is quite weird, but for file drag and drop, explorer
|
// this is quite weird, but for file drag and drop, explorer
|
||||||
// calls our SetData() with the formats we do *not* support!
|
// calls our SetData() with the formats we do *not* support!
|
||||||
//
|
//
|
||||||
@@ -459,6 +480,7 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
|
|||||||
size_t size;
|
size_t size;
|
||||||
switch ( format )
|
switch ( format )
|
||||||
{
|
{
|
||||||
|
case wxDF_HTML:
|
||||||
case CF_TEXT:
|
case CF_TEXT:
|
||||||
case CF_OEMTEXT:
|
case CF_OEMTEXT:
|
||||||
size = strlen((const char *)pBuf);
|
size = strlen((const char *)pBuf);
|
||||||
@@ -567,6 +589,8 @@ STDMETHODIMP wxIDataObject::QueryGetData(FORMATETC *pformatetc)
|
|||||||
|
|
||||||
// and now check the type of data requested
|
// and now check the type of data requested
|
||||||
wxDataFormat format = pformatetc->cfFormat;
|
wxDataFormat format = pformatetc->cfFormat;
|
||||||
|
format = HtmlFormatFixup(format);
|
||||||
|
|
||||||
if ( m_pDataObject->IsSupportedFormat(format) ) {
|
if ( m_pDataObject->IsSupportedFormat(format) ) {
|
||||||
wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: %s ok"),
|
wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: %s ok"),
|
||||||
wxGetFormatName(format));
|
wxGetFormatName(format));
|
||||||
|
@@ -128,6 +128,10 @@ void wxDataFormat::SetType( wxDataFormatId dataType )
|
|||||||
m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.utf16-plain-text") );
|
m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.utf16-plain-text") );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case wxDF_HTML:
|
||||||
|
m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.html") );
|
||||||
|
break;
|
||||||
|
|
||||||
case wxDF_BITMAP:
|
case wxDF_BITMAP:
|
||||||
m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.tiff") );
|
m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.tiff") );
|
||||||
break;
|
break;
|
||||||
@@ -158,6 +162,10 @@ void wxDataFormat::SetId( NativeFormat format )
|
|||||||
m_format = 0;
|
m_format = 0;
|
||||||
}
|
}
|
||||||
m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)format);
|
m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)format);
|
||||||
|
if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.html") ) )
|
||||||
|
{
|
||||||
|
m_type = wxDF_HTML;
|
||||||
|
}
|
||||||
if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.utf16-plain-text") ) )
|
if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.utf16-plain-text") ) )
|
||||||
{
|
{
|
||||||
m_type = wxDF_UNICODETEXT;
|
m_type = wxDF_UNICODETEXT;
|
||||||
|
Reference in New Issue
Block a user