搜索
熱搜: 活動 交友 discuz
查看: 1758|回復: 0
打印 上一主題 下一主題

[教學] wxWidget 2.6.3的一個 BUG

[複製鏈接]
跳轉到指定樓層
1#
發表於 2007-7-27 20:50:59 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
wxTextCtrl繼承自wxTextCtrlBase,而wxTextCtrlBase繼承自std::streambuf
std::streambuf是窄字節的
typedef basic_streambuf<char, char_traits<char> > streambuf;
於是在寬字符(wide char)版的wxWidget中,就出現了亂碼問題。
示例代碼
wxTextCtrl* debugOutput;
std::ostream *logStream;
....
logStream=new std::ostream(debugOutput);
*logStream<<"你好"<<std::endl;

亂碼的原因在於 streambuf 讀取字符是一個字節(byte)、一個字節的讀取的。
streambuf中的字符采用的是變長(multibyte)編碼。
而wxTextCtrlBase中的實現
int wxTextCtrlBase::overflow(int c)
{
AppendText((wxChar)c);

// return something different from EOF
return 0;
}
是把streambuf的每個單字節,當作一個unicode字符,插入到TextCtrl之中。
於是,以GB2312/GBK方式編碼的"你好"這樣兩個漢字,就會被分割成4個unicode字符。

此外,wxTextCtrl的destructor不是虛的。如果我要從這裡通過繼承的方式修改overflow函數的行為,
需要承擔一定的風險。

如果我一定要這麼做,我必須在overflow函數中引入靜態變量才能解決問題。如此一來,這個函數就不是線程安全的了
於是我修改了兩個源文件,做了一個patch

--- textctrl.h.orig 2005-06-13 1316.000000000 +0800
+++ textctrl.h 2006-12-11 00:18:55.812500000 +0800
@@ -267,7 +267,7 @@

class WXDLLEXPORT wxTextCtrlBase : public wxControl
#if wxHAS_TEXT_WINDOW_STREAM
- , public wxSTD streambuf
+ , public wxSTD basic_streambuf<wxChar, wxSTD

c
har_traits<wxChar> >
#endif

{
@@ -384,7 +384,7 @@

// override streambuf method
#if wxHAS_TEXT_WINDOW_STREAM
- int overflow(int i);
+ int_type overflow(int_type i);
#endif // wxHAS_TEXT_WINDOW_STREAM

// stream-like insertion operators: these are always available, whether

we
@@ -520,12 +520,12 @@

public:
wxStreamToTextRedirector(wxTextCtrl *text)
- : m_ostr(wxSTD cout)
+ : m_ostr(wxSTD wcout)
{
Init(text);
}

- wxStreamToTextRedirector(wxTextCtrl *text, wxSTD ostream *ostr)
+ wxStreamToTextRedirector(wxTextCtrl *text, wxSTD wostream *ostr)
: m_ostr(*ostr)
{
Init(text);
@@ -538,10 +538,10 @@

private:
// the stream we're redirecting
- wxSTD ostream& m_ostr;
+ wxSTD wostream& m_ostr;

// the old streambuf (before we changed it)
- wxSTD streambuf *m_sbufOld;
+ wxSTD wstreambuf *m_sbufOld;
};

#endif // wxHAS_TEXT_WINDOW_STREAM


textcmn.cpp:
int wxTextCtrlBase::overflow(int c)
{
AppendText((wxChar)c);

// return something different from EOF
return 0;
}
修改為
wxTextCtrlBase::int_type wxTextCtrlBase::overflow(wxTextCtrlBase::int_type c)
{
AppendText((wxChar)c);

// return something different from EOF
return 0;
}

期待著這個patch被check in到cvs中去
您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則

本論壇為非營利之網路平台,所有文章內容均為網友自行發表,不代表論壇立場!若涉及侵權、違法等情事,請告知版主處理。


Page Rank Check

廣告刊登  |   交換連結  |   贊助我們  |   服務條款  |   免責聲明  |   客服中心  |   中央分站

手機版|中央論壇

GMT+8, 2024-4-29 06:29 , Processed in 0.498673 second(s), 16 queries .

Powered by Discuz!

© 2005-2015 Copyrights. Set by YIDAS

快速回復 返回頂部 返回列表