DeskAngel

Desktop softwares and information

Follow me on TwitterRSS Feeds

  • Home
  • DeskAngel
  • Oolauncher
  • Wsizer

Google market alternative

Mar 10th

Posted by WilliamX in Information

No comments

Google market is not supported in China and it is hard to publish android applications to it from China mainland, even if your application is a free version.

I did some search and find some alternative sites which accept android applications.:

SlideME (https://slideme.org/ ), I uploaded my first android application Days and date to it yesterday.

MOBANGO (http://www.mobango.com/), it more like a social community than an application download site.

android

十进制整数到字符串的转换

Mar 4th

Posted by WilliamX in Programming

No comments

今天被问到了这个问题,一下子卡壳,没有回答上来。

十进制比如12345如何转换成字符串?基本思路是要把每一位整数单独提取出来。

一万二千三百四十五,如何提取每一位?其实也简单:

12345 / 10000 = 1;
12345 % 10000 = 2345;

取出的模再来一遍:

2345 / 1000 = 2;
2345 % 1000 = 345;

以此类推。

这算法在我自己的函数库中都有过实现,关键时刻却不记得了。老了吗?sigh~

c++, tips
snap20100302_172708

Days and Date

Mar 2nd

Posted by WilliamX in Software

No comments


DaysandDate是我第一个Android程序,嗯,也是我第一个java程序。好吧,我承认这个界面有点简陋,也许等我找到一个美工之后才有可能改善。(如果你有好的设计并愿意合作,可以给我email: william.xue AT gmail.com)

这个程序的功能是使用修正儒略日在两个日期和天数之间进行换算。直白一点就是计算:
1. 某个两个日期之间间隔的天数
2. 某个日期加上或减去若干天之后是哪一天

计算完后会显示这两个日期所对应的星期,点击等于号后面的按钮可以把整个计算表达式保持到历史记录里面。之所以没有自动保持,是因为改变任意一个数值程序都会进行计算并更新,没有必要保存下来。

功能比较简单,但是比较使用,可以用来计算还有多少天女友过生日,与女友认识了多少天等等。

点此下载 (v2.1,新版本可以在Android Market找到)

android, DaysAndDate

DeskAngel convert path text to paste-able object

Feb 24th

Posted by WilliamX in Software

No comments

From the DeskAngel version v2.2.2.66, two new features are introduced. You can see two new menu items in the shortcut menu:

  1. Path to pastable object
  2. Pastable object to path

Use cases:
If you copied a path from somewhere, e.g. log file, then click “Path to pastable object”, you can paste it just as you copied the file itself.

If you copied a file but you want to get the full path of it, you can click “Pastable object to path”, then when you do paste in a text edit, you get the full path.

Both features are very useful sometimes. Hope you will like them and any feedback is welcome.

You can get the latest version from  here.

deskangel
information of _iob

Windows命令行窗口与Unicode

Feb 23rd

Posted by WilliamX in Programming

No comments

一.

还记得刚开始学习C语言的时候,最早接触的runtime函数,就是printf,这应该是一个最基础的函数了。
但是这样的一个函数,即使在VC2005和Windows 7下面,对输出Unicode字符这样的任务,依然会给程序员带了麻烦。

下面的代码是一个Unicode版本的测试程序:

int wmain(int argc, wchar_t **argv)
{
    wprintf(L"测试");

    return 0;
}

看着完全没有问题,但是在console中就是没有任何的输出。

二.

单步进入wprintf,发现如下代码:

        retval = _woutput_l(stdout,format,NULL,arglist);

其中,宏stdout为标准输出,定义如下:

#define stdout (&__iob_func()[1])

__iob_func的代码如下:

/* These functions are for enabling STATIC_CPPLIB functionality */
_CRTIMP FILE * __cdecl __iob_func(void)
{
    return _iob;
}

_iob是一个FILE类型的数组,第0个元素为stdin,第1个元素为stdout,第3个为stderr。
而FILE类型是一个结构体:

struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
        };
typedef struct _iobuf FILE;

_iob在调试器中的信息 (点击查看原图):
information of _iob

从图中可以看出,std本身就不支持UNICODE。

三.

我们还可以更深入一点,进入_woutput_l函数,会发现该函数调用
WRITE_CHAR(ch, &charsout);
宏逐个输出字符。

该宏的定义和_woutput_l在同一个文件(output.c)中找到:

#define WRITE_CHAR(ch, pnw)         write_char(ch, stream, pnw)

其中ch为第一个字符,“测”;stream为_woutput_l的第一个参数,就是stdout。

四.

write_char的代码很简单:

LOCAL(void) write_char (
    _TCHAR ch,
    FILE *f,
    int *pnumwritten
    )
{
    if ( (f->_flag & _IOSTRG) && f->_base == NULL)
    {
        ++(*pnumwritten);
        return;
    }
#ifdef _UNICODE
    if (_putwc_nolock(ch, f) == WEOF)
#else  /* _UNICODE */
    if (_putc_nolock(ch, f) == EOF)
#endif  /* _UNICODE */
        *pnumwritten = -1;
    else
        ++(*pnumwritten);
}

五.

进入_fputwc_nolock(即_putwc_nolock)。该函数的声明为:

wint_t __cdecl _fputwc_nolock (
        wchar_t ch,
        FILE *str
        )

函数中对str有三个判断,

if (_textmode_safe(_fileno(str)) == __IOINFO_TM_UTF16LE)
{
...
}
else if (_textmode_safe(_fileno(str)) == __IOINFO_TM_UTF8)
{
...
}
else if ((_osfile_safe(_fileno(str)) & FTEXT))
{
...
}

第一第二个判断很明显,判断目标文件是否为UTF16 little endian编码和UTF8编码。
对stdout,这里会进入第三个判断,其中FTEXT表示文件句柄为文本模式。
在该条件下,函数接着调用wctomb_s:

wctomb_s(&size, mbc, MB_LEN_MAX, ch)

做编码转换,即试图把wide char的ch转换为multi-byte的mbc。

六.

wctomb_s调用_wctomb_s_l,仅仅把locale参数设为NULL:

extern "C" errno_t __cdecl wctomb_s (
        int *pRetValue,
        char *dst,
        size_t sizeInBytes,
        wchar_t wchar
        )
{
        return _wctomb_s_l(pRetValue, dst, sizeInBytes, wchar, NULL);
}

七.

_wctomb_s_l函数是wctomb_s的locale版,根据locale做不同的工作。声明如下:

extern "C" int __cdecl _wctomb_s_l (
        int *pRetValue,
        char *dst,
        size_t sizeInBytes,
        wchar_t wchar,
        _locale_t plocinfo
        )

函数对locale有一个判断,

if ( _loc_update.GetLocaleT()->locinfo->lc_handle[LC_CTYPE] == _CLOCALEHANDLE )
{
        if ( wchar > 255 )  /* validate high byte */
        {
            if (dst != NULL && sizeInBytes > 0)
            {
                memset(dst, 0, sizeInBytes);
            }
            errno = EILSEQ;
            return errno;
        }

        if (dst != NULL)
        {
            _VALIDATE_RETURN_ERRCODE(sizeInBytes > 0, ERANGE);
            *dst = (char) wchar;
        }
        if (pRetValue != NULL)
        {
            *pRetValue = 1;
        }
        return 0;
}
else
{
...
}

如果locale是C locale的话,那么当wchar大于255,即超出ANSI范围时,不做转换,直接返回;
小于255,即为ANSI字符时,则转换为char类型。

如果不是c locale,则调用WideCharToMultiByte:

        if ( ((size = WideCharToMultiByte( _loc_update.GetLocaleT()->locinfo->lc_codepage,
                                           0,
                                           &wchar,
                                           1,
                                           dst,
                                           (int)sizeInBytes,
                                           NULL,
                                           &defused) ) == 0) ||
             (defused) )

测试代码没有设置locale,所以判断wchar,自然大于255,函数直接返回。层层返回,没有调用任何实际的输出。

八.

稍稍修改一下测试程序:

int wmain(int argc, wchar_t **argv)
{
    wprintf(L"%s", L"测试");

    return 0;
}

输出的是两个问号。单步跟踪,我们可以发现,在_woutput_l中,没有直接调用WRITE_CHAR,而是调用WRITE_STRING:

WRITE_STRING(text.wz, textlen, &charsout);

WRITE_STRING的代码:

LOCAL(void) write_string (
    _TCHAR *string,
    int len,
    FILE *f,
    int *pnumwritten
    )
{
    if ( (f->_flag & _IOSTRG) && f->_base == NULL)
    {
        (*pnumwritten) += len;
        return;
    }
    while (len-- > 0) {
        write_char(*string++, f, pnumwritten);
        if (*pnumwritten == -1)
        {
            if (errno == EILSEQ)
                write_char(_T('?'), f, pnumwritten);
            else
                break;
        }
    }
}

在write_char写入Unicode字符失败后,就会写入一个”?”,所以输出的会是问号。

九.

如何输出Unicode呢?有两个方法:
1. 设置正确的locale。
我们看到整个过程最后会调用WideCharToMultiByte把Unicode根据locale转换成multiple byte。
这可以解决一点问题,但不完美。除了绕了个圈,又把wide char转换成multiple byte之外,还无法解决多种语言混合输出的问题。
比如,无法同时输出俄文和中文。

2. 使用WriteConsole。
如下代码可以完美的解决Unicode的问题:

    wchar_t szText[] = L"测试";

    HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    WriteConsole(hStdOutput, szText, (DWORD)wcslen(szText), NULL, NULL);
c++, locale, printf, stdout, unicode
« First...«34567»...Last »
  • Tags

    AdjBrightness aero android c++ DaCalc DaysAndDate deskangel eclipse emacs formula gnupgp gpg4win iphone latitude locale mac ntfs object oriented oolauncher openpgp opera photo Prince of Persia printf psi regular expression speedcommander stdout symbol link The Forgotten Sands tips unicode virtual memory vs2010 wii wildcard win7 wine working set wsizer
  • DeskAngel Sites

    • DeskAngel
    • Oolauncher
    • Wsizer
  • Other links

    • wkcow
    • 沧海一粟
  • Calendar

    September 2010
    S M T W T F S
    « Aug    
     1234
    567891011
    12131415161718
    19202122232425
    2627282930  
  • Recent Posts

    • Share DaysAndDate and get Ads removal code
    • error RC1106: invalid option: -ologo
    • 使用wine在Mac上运行Win程序
    • Adjust brightness for Android devices
    • 波斯王子:遗忘之沙(WII)剧情
  • Recent Comments

    • Josh on Adjust brightness for Android devices
    • WilliamX on Adjust brightness for Android devices
    • Josh on Adjust brightness for Android devices
    • Deeznutz1977 on Adjust brightness for Android devices
    • WilliamX on Adjust brightness for Android devices
  • Archives

    • August 2010 (1)
    • July 2010 (3)
    • June 2010 (2)
    • May 2010 (2)
    • April 2010 (6)
    • March 2010 (9)
    • February 2010 (5)
    • January 2010 (1)
    • October 2009 (1)
    • September 2009 (3)
    • July 2009 (1)
    • June 2009 (3)
    • March 2009 (3)
    • February 2009 (7)
  • Categories

    • Critique
    • Information
    • News
    • Programming
    • Software
    • Source
  • Meta

    • Register
    • Log in
    • Entries RSS
    • Comments RSS
    • WordPress.org
  • My latest tweets

    Loading tweets...
    Follow me on Twitter!
Mystique theme by digitalnature | Powered by WordPress
RSS Feeds XHTML 1.1 Top