Wxwidgets和C#的感悟

来源:互联网 发布:宝宝创意照片软件 编辑:程序博客网 时间:2024/05/16 18:39
本来想开发一个跨平台的程序,一个跨平台的WebServer,Linux, MAC,Windows CE
用WxWidgets写了很久,用了WxSqlite来连接数据库,一切看上去都那么顺利。
我用的是Unicode的编译方式,开始没有预料到编码是个问题,但是慢慢编码问题开始显露
我发现,WxWidgets处理编码问题远没有C#牛逼。
举个例子,在C#里面我们可以这么写

string x = System.Web.HttpUtility.UrlEncode("刘", Encoding.GetEncoding(936));
%C1%F5
string x = System.Web.HttpUtility.UrlEncode("刘", Encoding.UTF8);
%E5%88%98
string x = System.Web.HttpUtility.UrlEncode("刘", Encoding.Unicode);
%18R

无论如何,这些带着百分号的编码,或者是经过Base64的编码,或者是javascript里面escape的编码,比如%u5218
我在Wxwidgets的Unicode模式下尝试了很多的方法,但是没有一种方法能够正确进行URLdecode展现出“刘”这个字。
然而,在ANSI方式下的Wxwidgets就可以轻松URLdecode展现“刘”字。
我承认不是widgets不好,只是我的技术水平不够,还不知道怎么转换。
在这里附上我尝试的一些代码段,纪念一下我使用过可爱的wxwidgets。以后慢慢研究怎么在unicode模式下正确urldecode好了。



#define SPC_BASE16_TO_10(x) (((x) >= '0' && (x) <= '9') ? ((x) - '0') : /
                             (toupper((x)) - 'A' + 10))

wxString UrlDecode(wxString &url) {
  size_t i=0;
  wxString dest;
  for (i = 0;  i<url.length();  i++) {
    if (url[i] == '+') dest += ' ';
  else if (url[i] != '%' || !isxdigit(url[i + 1]) || !isxdigit(url [i + 2])) dest += url[i];
    else {
      dest += (SPC_BASE16_TO_10(url[i + 1]) * 16) + (SPC_BASE16_TO_10(url [i + 2]));
      i += 2;
    }
  }
  return dest;
}

wxString URLEncode(const wxString &str) 
{
    wxString ret;
    wxString t;
    for(unsigned int i = 0; i < str.length(); ++i)
    {
        wxChar c = str[i];
        if(   (c >= _T('A') && c <= _T('Z'))
           || (c >= _T('a') && c <= _T('z'))
           || (c >= _T('0') && c <= _T('9'))
           ||  c == _T('.') || c == _T('-') || c == _T('_') )

            ret.Append(c);
        else if(c == _T(' '))
            ret.Append(_T('+'));
        else
        {
            t.sprintf(_T("%%%02X"), (unsigned int) c);
            ret.Append(t);
        }
    }
    return ret;
}

static byte base16Chars[17] = "0123456789ABCDEF";

wxString URLEncode2(wxString sIn)
{
  wxString sOut;
  unsigned char curChar;

  for ( unsigned int i = 0; i < sIn.Length(); i ++ ) {
    curChar = sIn.GetChar( i );

    if ( isalnum( curChar ) ) {
          sOut += curChar;
      } else if( isspace ( curChar ) ) {
        sOut += wxT("+");
    } else {
      sOut += wxT("%");
      sOut += base16Chars[ curChar >> 4];
      sOut += base16Chars[ curChar & 0xf];
    }

  }

  return sOut;
}
inline bool shouldEncode(char c){
  if(c>='0' && c<='9') return false;
  if(c>='a' && c<='z') return false;
  if(c>='A' && c<='Z') return false;
  if(c=='(' || c==')' || c=='$' || c=='!' || c=='*' || c==',' || c=='-' || c=='.' || c=='/' || c=='=' || c==':' || c=='?' || c=='@') return false;
  return true;
}

wxString UrlEncode3(wxString source){
  static const char *hex = "0123456789abcdef";

  unsigned char ch;
  wxString dest;
  size_t source_index = 0;
  while(source.length()>source_index)
  {
    ch = (unsigned char)source[source_index];
    if(source[source_index] == ' ')
      dest += '+';
    else if( !shouldEncode(source[source_index])/* || source[source_index] == '/' || source[source_index] == '.'*/)
      dest += source[source_index];
    else
    {
      dest += '%';
      dest += hex[(ch >> 4)&0xF];
      dest += hex[ch % 16];
    }
    source_index++;
  }
  return dest;
}
wxString UrlDecode3(wxString &url) {
  size_t i=0;
  wxString dest;
  for (i = 0;  i<url.length();  i++) {
    if (url[i] == '+') dest += ' ';
  else if (url[i] != '%' || !isxdigit(url[i + 1]) || !isxdigit(url [i + 2])) dest += url[i];
    else {
      dest += (SPC_BASE16_TO_10(url[i + 1]) * 16) + (SPC_BASE16_TO_10(url [i + 2]));
      i += 2;
    }
  }
  return dest;
}


void URLEncode6(char*& data)
{
  static char* hdig = ("0123456789abcdef");

  char*  obuf = new char[strlen(data) * 3 + 1];
  char*  optr = obuf;

  char*  dptr = data;

  while (*dptr)
  {
    if (((*dptr >= 'a') && (*dptr <= 'z')) ||
      ((*dptr >= 'A') && (*dptr <= 'Z')) ||
      ((*dptr >= '0') && (*dptr <= '9')) ||
      (*dptr == '/') || (*dptr == '-') || (*dptr == ':') || (*dptr == '#'))
    {
      *optr++ = *dptr++;
    }
    else
    {
      *optr++ = '%';
      *optr++ = hdig[(*dptr >> 4) & 15];
      *optr++ = hdig[*dptr & 15];
      dptr++;
    }
  }
  *optr++ = '/0';
  delete[] data;
  data = obuf;
}




/*
  wxString xe= wxT("%C1%F5");
  wxString x= wxT("%E5%88%98");
  char* x3="%E5%88%98";
  wxString x2=UrlDecode(x);
  //wxString x4=wxHTTPBuilder::Base64Encode(wxT("刘"));
  //wxString x5=wxHTTPBuilder::Base64Decode(x4);
  wxString s=wxHTTPBuilder::URLDecode(xe);
  const wxCharBuffer xs=s.mb_str(wxConvUTF8);
  //const wxCharBuffer x7=wxConvUTF8.cMB2WX(((const wchar_t *)(s).c_str()));
  //wxString xx43=wxString(s, wxConvLocal);

  //const char* x21=x7.data();

  //wxConvUTF8.cMB2WX(x3);
  */
  //char * sc="刘";
  //URLEncode6(sc);
  wxString s=URLEncode(wxT("%R18"));
  // s=UrlDecode3(s);
  wxString tt=s;


最后,我想说的是,C#的功劳就是把人们从繁重的基础工作中解脱出来,使人们专注于最关键的架构以及功能。
于是在这个意义上说,C#有着一定的优势,尤其是你很在乎你的开发时间的情况下。

顺便说一些心得,用vs2008生成的代码要比code::blocks生成的代码小。

还有就是wxPack真的很好用

还有就是,自己编译wxwidgets不用wxpack也是可以的,你想好了你用什么模式unicode static debug,你就编译那一种就好了,挺快的,5分钟!wiki上说什么要3个小时,那个是吓唬人的,他说的只是全部都编译了才那么多时间呢。不过确实很耗硬盘空间,即使你之编译一点。恩

wxsqlite3这个很好用,但是sqlite3.lib不好弄,要手动生成,生成方法是copy mspdb80.dll到lib.exe和link.exe的目录下,然后写一个bat,LIB /MACHINE:IX86 /DEF:sqlite.def
其实也很简单的,但是还是很麻烦!

另外不建议用mingw里面的编译器去编译wx,这个会很大,还是建议你用vs的,但是 vs的编译器在codeblock里面经常出问题,于是你直接用vs好了。

说实话,我讨厌unicode,更喜欢utf8

哦,还有,wxformbuilder在vs下好用,在codeblocks下不好用,建议你在codeblocks下面用wxsmith做GUI
另外wxformbuilder在vs下面生成的代码是不能改的,要继承,然后重写方法,这个好麻烦。也许有插件?不知道。

我讨厌wxConvUTF8,一点不人性化。

做服务器的一些心得:
如果你想返回404,你不能光写一个什么404 not found,你还要加上Headder和相关数据,才行。要不然IE就在那里不动了。
hr.SetRC(wxT("404 Not Found"));
hr.AddHeader(wxT("Content-Type: text/html; charset=UTF8") );
hr.AddDataLine( wxT( "Not Found") );




还有content_type也是很有意思的。

if (url_ext==wxT(".htm"))
                 return wxT("text/html");
  if (url_ext==wxT(".html"))
                 return wxT("text/html");
  if (url_ext==wxT(".gif"))
                 return wxT("image/gif");
  if (url_ext==wxT(".jpg")||url_ext==wxT(".jpeg"))
                 return wxT("image/jpeg");
  if (url_ext==wxT(".bmp"))
                 return wxT("image/bitmap");
  if (url_ext==wxT(".png"))
                 return wxT("image/png");
  if (url_ext==wxT(".gz") || url_ext==wxT(".zip")  || url_ext==wxT(".rar") || url_ext==wxT(".bz2") )
                 return wxT("application/binary");
  if (url_ext==wxT(".css"))
                 return wxT("text/css");
  if (url_ext==wxT(".js"))
                 return wxT("application/x-javascript");
  if (url_ext==wxT(".xml"))
                 return wxT("text/xml");
  if (url_ext==wxT(".pdf"))
                 return wxT("application/pdf");

    return wxT("text/plain");

原创粉丝点击