Exemplo n.º 1
0
/* Strips "\\\\?\\" extended prefix or
 * "\\??\\" NT Object Manager prefix from
 * @str in-place, using memmove.
 * @str_size must point to the size of @str
 * in gunichar2s, including NUL-terminator
 * (if @str is NUL-terminated; it doesn't have to be).
 * On return @str_size will correctly reflect changes
 * in @str size (if any).
 * Returns TRUE if @str was modified.
 */
static gboolean
_g_win32_strip_extended_ntobjm_prefix (gunichar2 *str,
                                       gsize     *str_size)
{
  const wchar_t *extended_prefix = L"\\\\?\\";
  const gsize    extended_prefix_len = wcslen (extended_prefix);
  const gsize    extended_prefix_len_bytes = sizeof (gunichar2) * extended_prefix_len;
  const gsize    extended_prefix_with_drive_len_bytes = sizeof (gunichar2) * (extended_prefix_len + 2);
  const wchar_t *ntobjm_prefix = L"\\??\\";
  const gsize    ntobjm_prefix_len = wcslen (ntobjm_prefix);
  const gsize    ntobjm_prefix_len_bytes = sizeof (gunichar2) * ntobjm_prefix_len;
  const gsize    ntobjm_prefix_with_drive_len_bytes = sizeof (gunichar2) * (ntobjm_prefix_len + 2);
  gboolean do_move = FALSE;
  gsize move_shift = 0;

  if ((*str_size) * sizeof (gunichar2) > extended_prefix_with_drive_len_bytes &&
      memcmp (str,
              extended_prefix,
              extended_prefix_len_bytes) == 0 &&
      iswascii (str[extended_prefix_len]) &&
      iswalpha (str[extended_prefix_len]) &&
      str[extended_prefix_len + 1] == L':')
   {
     do_move = TRUE;
     move_shift = extended_prefix_len;
   }
  else if ((*str_size) * sizeof (gunichar2) > ntobjm_prefix_with_drive_len_bytes &&
           memcmp (str,
                   ntobjm_prefix,
                   ntobjm_prefix_len_bytes) == 0 &&
           iswascii (str[ntobjm_prefix_len]) &&
           iswalpha (str[ntobjm_prefix_len]) &&
           str[ntobjm_prefix_len + 1] == L':')
    {
      do_move = TRUE;
      move_shift = ntobjm_prefix_len;
    }

  if (do_move)
    {
      *str_size -= move_shift;
      memmove (str,
               str + move_shift,
               (*str_size) * sizeof (gunichar2));
    }

  return do_move;
}
Exemplo n.º 2
0
Arquivo: fmt.c Projeto: alhazred/onarm
static int
_wckind_c_locale(wchar_t wc)
{
	int	ret;

	/*
	 * DEPEND_ON_ANSIC: L notion for the character is new in
	 * ANSI-C, k&r compiler won't work.
	 */
	if (iswascii(wc))
		ret = (iswalnum(wc) || wc == L'_') ? 0 : 1;
	else
		ret = wcsetno(wc) + 1;

	return (ret);
}
Exemplo n.º 3
0
void CLyricsDlg::LoadFromFile(HWND hDlg)
{
	OPENFILENAME ofn;
	ZeroMemory(&ofn, sizeof(ofn));
	wchar_t strFile[260];

	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = hDlg;
	ofn.lpstrFilter = L"Fișiere Text (*.txt)\0*.txt\0\0";
	ofn.nFilterIndex = 1;
	ofn.lpstrFile = strFile;
	ofn.lpstrFile[0] = 0;
	ofn.nMaxFile = sizeof(strFile);
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

	// Display the Open dialog box. 

	if (GetOpenFileName(&ofn)==TRUE)
	{
		HANDLE hFile = CreateFile(ofn.lpstrFile, GENERIC_READ, FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES) NULL, 
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);

		byte xch[2], ch;
		string str;
		byte dUnicode = 0;//0 = ANSI, 1 = UTF-8, 2 = UTF-16(FF FE) 3 = UTF-16BE (FE FF)
		DWORD dwRead;
		if (0 == ReadFile(hFile, xch, 2, &dwRead, 0))
		{
			MessageBoxA(hDlg, "Error! The file could not be read!", "Error!", MB_ICONERROR);
#ifdef _DEBUG
			DebugBreak();
#endif
			return;
		}

		if (xch[0]==0xFF && xch[1]==0xFE)
			dUnicode = 2;
		else if (xch[0]==0xFE && xch[1]==0xFF)
			dUnicode = 3;
		else if (!( __isascii(xch[0]) &&  __isascii(xch[1]) 
			|| iswascii(MAKEWORD(xch[0], xch[1]))))
		{
			if (MessageBoxW(hDlg, L"Fișierul ar putea fi afișat incorect datorită codării. Vrei să continui așa?", L"Problemă de codificare", MB_ICONEXCLAMATION | MB_YESNO) == IDNO)
				return;
		}

		if (!dUnicode)
			SetFilePointer(hFile, 0, 0, FILE_BEGIN);
		DWORD dwSize = GetFileSize(hFile, 0);
		byte* buffer = new byte[dwSize];
		ReadFile(hFile, buffer, dwSize, &dwRead, 0);
		if (dUnicode == 2)//FF FE
		{
//			while (ReadFile(hFile, xch, 2, &dwRead, 0) )
			for (int i = 0; i < dwSize-1; i += 2)
			{
				xch[0] = buffer[i]; xch[1] = buffer[i+1];
				if (xch[1]==0 && xch[0]!='\r') 
					str += xch[0];
			}
		}
		else if (dUnicode == 3)//FE FF
		{
			for (int i = 0; i < dwSize-1; i += 2)
			{
				xch[0] = buffer[i]; xch[1] = buffer[i+1];
				if (xch[0]==0 && xch[1]!='\r') 
					str += xch[1];
			}
		}
		else
		{
			for (int i = 0; i < dwSize; i++)
//			while (ReadFile(hFile, &ch, 1, &dwRead, 0))
			{
				ch = buffer[i];
				if (dwRead == 0) break;
				if (ch!='\r') str += ch;
			}
		}
		delete[] buffer;

		CloseHandle(hFile);
		SetList(hDlg, str);
	}
}
Exemplo n.º 4
0
void CSoftUninstall::GetPinYin(const std::wstring &name, std::wstring &whole, std::wstring &acronym)
{
	typedef list<string>					str_list;
	typedef str_list::iterator				str_iter;
	typedef string_tokeniser<string, char>	string_tokeniser_a;

	typedef void (string::*PFPushback)(char);
	typedef string& (string::*PFAppend)(const char*);

	PFAppend pfAppend = &string::append;
	PFPushback pfPushback = &string::push_back;

	char mbcs[5];
	str_list wholeList, acronymList;
	wholeList.push_back(string());
	acronymList.push_back(string());

	for(wstring::size_type i = 0; i < name.size(); ++i)
	{
		if(iswascii(name[i]) == 0)
		{	// 非ASCII码
			int ret;
			if(wctomb_s(&ret, mbcs, sizeof(mbcs), name[i]) != 0) continue;
			mbcs[ret] = '\0';

			PinYinCIter itPinYin = _hashPinYin.find(mbcs);
			if(itPinYin != _hashPinYin.end())
			{
				const PinYin &pinyin = itPinYin->second;

				// M X N组合
				{
					string_tokeniser_a tokeniser(pinyin._whole, ' ');

					str_list resultList;
					string_tokeniser_a::const_iterator end = tokeniser.end();
					for(string_tokeniser_a::const_iterator it = tokeniser.begin(); it != end; ++it)
					{
						str_iter endList = wholeList.end();
						for(str_iter itList = wholeList.begin(); itList != endList; ++itList)
							resultList.push_back(*itList + *it);
					}
					wholeList.swap(resultList);
				}
				{
					string_tokeniser_a tokeniser(pinyin._acronym, ' ');

					str_list resultList;
					string_tokeniser_a::const_iterator end = tokeniser.end();
					for(string_tokeniser_a::const_iterator it = tokeniser.begin(); it != end; ++it)
					{
						str_iter endList = acronymList.end();
						for(str_iter itList = acronymList.begin(); itList != endList; ++itList)
							resultList.push_back(*itList + *it);
					}
					acronymList.swap(resultList);
				}
			}
			else
			{
				for_each(wholeList.begin(), wholeList.end(), bind2nd(mem_fun1_ref(pfAppend), mbcs));
				for_each(acronymList.begin(), acronymList.end(), bind2nd(mem_fun1_ref(pfAppend), mbcs));
			}
		}
		else
		{
			// ASCII码直接组合
			for_each(wholeList.begin(), wholeList.end(), bind2nd(mem_fun1_ref(pfPushback), (char)towlower(name[i])));
			for_each(acronymList.begin(), acronymList.end(), bind2nd(mem_fun1_ref(pfPushback), (char)tolower(name[i])));
		}
	}

	// 合并结果
	{
		ostringstream os;
		copy(wholeList.begin(), wholeList.end(), ostream_iterator<string>(os, " "));

		whole = CA2W(os.str().c_str());
		trim_right(whole);
	}

	{
		ostringstream os;
		copy(acronymList.begin(), acronymList.end(), ostream_iterator<string>(os, " "));

		acronym = CA2W(os.str().c_str());
		trim_right(acronym);
	}
}
Exemplo n.º 5
0
/*--------------------------------------------------------------------------*/
static int isasciiStrings(char *fname, int *piAddressVarOne)
{
    SciErr sciErr;
    int m1 = 0, n1 = 0;
    wchar_t **pwcStVarOne = NULL;
    int *lenStVarOne = NULL;

    sciErr = getVarDimension(pvApiCtx, piAddressVarOne, &m1, &n1);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
        return 0;
    }

    lenStVarOne = (int*)MALLOC(sizeof(int) * (m1 * n1));

    if (lenStVarOne)
    {
        BOOL *bOutputMatrix = NULL;
        int i = 0;
        int lengthAllStrings = 0;

        sciErr = getMatrixOfWideString(pvApiCtx, piAddressVarOne, &m1, &n1, lenStVarOne, NULL);
        if (sciErr.iErr)
        {
            if (lenStVarOne)
            {
                FREE(lenStVarOne);
                lenStVarOne = NULL;
            }

            printError(&sciErr, 0);
            Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
            return 0;
        }

        pwcStVarOne = (wchar_t**)MALLOC(sizeof(wchar_t*) * (m1 * n1));
        for (i = 0; i < (m1 * n1); i++)
        {
            lengthAllStrings = lengthAllStrings + lenStVarOne[i];

            pwcStVarOne[i] = (wchar_t*)MALLOC(sizeof(wchar_t) * (lenStVarOne[i] + 1));

            if (pwcStVarOne[i] == NULL)
            {
                if (lenStVarOne)
                {
                    FREE(lenStVarOne);
                    lenStVarOne = NULL;
                }

                freeArrayOfWideString(pwcStVarOne, m1 * n1);
                Scierror(999, _("%s: Memory allocation error.\n"), fname);
                return 0;
            }
        }

        sciErr = getMatrixOfWideString(pvApiCtx, piAddressVarOne, &m1, &n1, lenStVarOne, pwcStVarOne);
        if (sciErr.iErr)
        {
            if (lenStVarOne)
            {
                FREE(lenStVarOne);
                lenStVarOne = NULL;
            }

            freeArrayOfWideString(pwcStVarOne, m1 * n1);
            printError(&sciErr, 0);
            Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
            return 0;
        }

        bOutputMatrix = (BOOL*)MALLOC(sizeof(BOOL) * lengthAllStrings);
        if (bOutputMatrix)
        {
            int mOut = 0;
            int nOut = 0;
            int x = 0;

            for (i = 0; i < (m1 * n1); i++)
            {
                int j = 0;
                wchar_t* wcInput = pwcStVarOne[i];
                int len = (int)wcslen(wcInput);

                for (j = 0; j < len; j++)
                {
                    if (iswascii(wcInput[j]))
                    {
                        bOutputMatrix[x] = (int)TRUE;
                    }
                    else
                    {
                        bOutputMatrix[x] = (int)FALSE;
                    }
                    x++;
                }
            }

            mOut = 1;
            nOut = lengthAllStrings;

            sciErr = createMatrixOfBoolean(pvApiCtx, Rhs + 1, mOut, nOut, bOutputMatrix);
            if (sciErr.iErr)
            {
                printError(&sciErr, 0);
                Scierror(999, _("%s: Memory allocation error.\n"), fname);
                return 0;
            }

            if (lenStVarOne)
            {
                FREE(lenStVarOne);
                lenStVarOne = NULL;
            }
            freeArrayOfWideString(pwcStVarOne, m1 * n1);
            if (bOutputMatrix)
            {
                FREE(bOutputMatrix);
                bOutputMatrix = NULL;
            }

            LhsVar(1) = Rhs + 1;
            PutLhsVar();
        }
        else
        {
            if (lenStVarOne)
            {
                FREE(lenStVarOne);
                lenStVarOne = NULL;
            }
            freeArrayOfWideString(pwcStVarOne, m1 * n1);
            Scierror(999, _("%s: Memory allocation error.\n"), fname);
        }
    }
    else
    {
        Scierror(999, _("%s: Memory allocation error.\n"), fname);
    }
    return 0;
}
Exemplo n.º 6
0
static int
_g_win32_fill_statbuf_from_handle_info (const wchar_t              *filename,
                                        const wchar_t              *filename_target,
                                        BY_HANDLE_FILE_INFORMATION *handle_info,
                                        struct __stat64            *statbuf)
{
  wchar_t drive_letter_w = 0;
  size_t drive_letter_size = MB_CUR_MAX;
  char *drive_letter = _alloca (drive_letter_size);

  /* If filename (target or link) is absolute,
   * then use the drive letter from it as-is.
   */
  if (filename_target != NULL &&
      filename_target[0] != L'\0' &&
      filename_target[1] == L':')
    drive_letter_w = filename_target[0];
  else if (filename[0] != L'\0' &&
           filename[1] == L':')
    drive_letter_w = filename[0];

  if (drive_letter_w > 0 &&
      iswalpha (drive_letter_w) &&
      iswascii (drive_letter_w) &&
      wctomb (drive_letter, drive_letter_w) == 1)
    statbuf->st_dev = toupper (drive_letter[0]) - 'A'; /* 0 means A: drive */
  else
    /* Otherwise use the PWD drive.
     * Return value of 0 gives us 0 - 1 = -1,
     * which is the "no idea" value for st_dev.
     */
    statbuf->st_dev = _getdrive () - 1;

  statbuf->st_rdev = statbuf->st_dev;
  /* Theoretically, it's possible to set it for ext-FS. No idea how.
   * Meaningless for all filesystems that Windows normally uses.
   */
  statbuf->st_ino = 0;
  statbuf->st_mode = 0;

  if ((handle_info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
    statbuf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
  else
    statbuf->st_mode |= S_IFREG;
  /* No idea what S_IFCHR means here. */
  /* S_IFIFO is not even mentioned in MSDN */
  /* S_IFBLK is also not mentioned */

  /* The aim here is to reproduce MS stat() behaviour,
   * even if it's braindead.
   */
  statbuf->st_mode |= S_IRUSR | S_IRGRP | S_IROTH;
  if ((handle_info->dwFileAttributes & FILE_ATTRIBUTE_READONLY) != FILE_ATTRIBUTE_READONLY)
    statbuf->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;

  if (!S_ISDIR (statbuf->st_mode))
    {
      const wchar_t *name;
      const wchar_t *dot = NULL;

      if (filename_target != NULL)
        name = filename_target;
      else
        name = filename;

      do
        {
          wchar_t *last_dot = wcschr (name, L'.');
          if (last_dot == NULL)
            break;
          dot = last_dot;
          name = &last_dot[1];
        }
      while (TRUE);

      if ((dot != NULL &&
          (wcsicmp (dot, L".exe") == 0 ||
           wcsicmp (dot, L".com") == 0 ||
           wcsicmp (dot, L".bat") == 0 ||
           wcsicmp (dot, L".cmd") == 0)))
        statbuf->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
    }

  statbuf->st_nlink = handle_info->nNumberOfLinks;
  statbuf->st_uid = statbuf->st_gid = 0;
  statbuf->st_size = (((guint64) handle_info->nFileSizeHigh) << 32) | handle_info->nFileSizeLow;
  statbuf->st_ctime = _g_win32_filetime_to_unix_time (&handle_info->ftCreationTime);
  statbuf->st_mtime = _g_win32_filetime_to_unix_time (&handle_info->ftLastWriteTime);
  statbuf->st_atime = _g_win32_filetime_to_unix_time (&handle_info->ftLastAccessTime);

  return 0;
}
	bool MyDynamicFontRects::UpdateVertexBufferByString(ID3D11DeviceContext* pDeviceContext, LPCWSTR pString,
		MyMath::Vector2F posInPixels,
		const MyMath::Vector4F& upperColor, const MyMath::Vector4F& lowerColor,
		long fontHeight, bool usesFixedFeed,
		uint32_t fontTexWidth, uint32_t fontTexHeight,
		const MyMath::TCharCodeUVMap& codeUVMap)
	{
		_ASSERTE(pString != nullptr);
		m_stringLength = 0;
		float offsetX = 0;
		TVertex* pVertexArray = &m_vertexArray[0]; // ローカル変数にキャッシュして高速化。
		for (int i = 0; pString[i] != 0 && i < MaxCharacterCount; ++i, ++m_stringLength)
		{
			// HACK: このアルゴリズム(というか単一の wchar_t キー)だと、サロゲート ペアにはどうしても対応不可能。
			const size_t charCode = static_cast<size_t>(pString[i]);
			if (charCode < codeUVMap.size())
			{
				const auto codeUV = codeUVMap[charCode];
				const float uvLeft   = static_cast<float>(codeUV.X) / fontTexWidth;
				const float uvTop    = static_cast<float>(codeUV.Y) / fontTexHeight;
				const float uvRight  = static_cast<float>(codeUV.GetRight()) / fontTexWidth;
				const float uvBottom = static_cast<float>(codeUV.GetBottom()) / fontTexHeight;
				const float uvWidth   = codeUV.Width;
				const float uvHeight  = codeUV.Height;
				// LT, RT, LB, RB.(0, 1, 2 は左手系の定義順)
				const size_t index0 = i * 4 + 0;
				// 文字の水平方向送り(カーニングは考慮しないが、プロポーショナルの場合は文字幅)。
				// スペースの文字送りも考慮する。
				// HUD 系は常にモノスペースのほうがいいこともある。
				// 非 ASCII はテクスチャ作成時にフォント メトリックから取得した文字幅にする。
				// ヨーロッパ言語など、非 ASCII でもモノスペース時は半角幅のほうがいい文字もあるが、それは考慮しない。
				// したがって、メソッドのフラグで等幅指定されたら、ASCII のみ半角幅とし、
				// 非 ASCII はフォント メトリックから取得した文字幅を使うようにする。
				const float feed = (usesFixedFeed && iswascii(pString[i])) ? (fontHeight / 2) : uvWidth;
				pVertexArray[index0].Position.x = posInPixels.x + offsetX;
				pVertexArray[index0].Position.y = posInPixels.y;
				pVertexArray[index0].Position.z = 0;
				//pVertexArray[index0].Position.w = 1;
				pVertexArray[index0].Color = upperColor;
				pVertexArray[index0].TexCoord.x = uvLeft;
				pVertexArray[index0].TexCoord.y = uvTop;
				const size_t index1 = i * 4 + 1;
				pVertexArray[index1].Position.x = posInPixels.x + offsetX + uvWidth;
				pVertexArray[index1].Position.y = posInPixels.y;
				pVertexArray[index1].Position.z = 0;
				//pVertexArray[index1].Position.w = 1;
				pVertexArray[index1].Color = upperColor;
				pVertexArray[index1].TexCoord.x = uvRight;
				pVertexArray[index1].TexCoord.y = uvTop;
				const size_t index2 = i * 4 + 2;
				pVertexArray[index2].Position.x = posInPixels.x + offsetX;
				pVertexArray[index2].Position.y = posInPixels.y + uvHeight;
				pVertexArray[index2].Position.z = 0;
				//pVertexArray[index2].Position.w = 1;
				pVertexArray[index2].Color = lowerColor;
				pVertexArray[index2].TexCoord.x = uvLeft;
				pVertexArray[index2].TexCoord.y = uvBottom;
				const size_t index3 = i * 4 + 3;
				pVertexArray[index3].Position.x = posInPixels.x + offsetX + uvWidth;
				pVertexArray[index3].Position.y = posInPixels.y + uvHeight;
				pVertexArray[index3].Position.z = 0;
				//pVertexArray[index3].Position.w = 1;
				pVertexArray[index3].Color = lowerColor;
				pVertexArray[index3].TexCoord.x = uvRight;
				pVertexArray[index3].TexCoord.y = uvBottom;

				// ボールド体の場合はもう少しオフセットしたほうがいいかも。
				// フォントによっては、強制的に半角幅分送るだけ、というのは問題あり。
				// 特にプロポーショナル フォントは英数字であっても文字幅が異なる。
				// モノスペースであっても、半角幅分とはかぎらない。
				offsetX += feed + 1;
			}
		}
		if (m_stringLength > 0)
		{
			return this->ReplaceVertexData(pDeviceContext, &m_vertexArray[0]);
		}
		else
		{
			return true;
		}
	}
Exemplo n.º 8
0
static void
cook_cat(FILE *fp)
{
	int ch, gobble, line, prev;
	wint_t wch;

	/* Reset EOF condition on stdin. */
	if (fp == stdin && feof(stdin))
		clearerr(stdin);

	line = gobble = 0;
	for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
		if (prev == '\n') {
			if (sflag) {
				if (ch == '\n') {
					if (gobble)
						continue;
					gobble = 1;
				} else
					gobble = 0;
			}
			if (nflag && (!bflag || ch != '\n')) {
				(void)fprintf(stdout, "%6d\t", ++line);
				if (ferror(stdout))
					break;
			}
		}
		if (ch == '\n') {
			if (eflag && putchar('$') == EOF)
				break;
		} else if (ch == '\t') {
			if (tflag) {
				if (putchar('^') == EOF || putchar('I') == EOF)
					break;
				continue;
			}
		} else if (vflag) {
			(void)ungetc(ch, fp);
			/*
			 * Our getwc(3) doesn't change file position
			 * on error.
			 */
			if ((wch = getwc(fp)) == WEOF) {
				if (ferror(fp) && errno == EILSEQ) {
					clearerr(fp);
					/* Resync attempt. */
					memset(&fp->_mbstate, 0, sizeof(mbstate_t));
					if ((ch = getc(fp)) == EOF)
						break;
					wch = ch;
					goto ilseq;
				} else
					break;
			}
			if (!iswascii(wch) && !iswprint(wch)) {
ilseq:
				if (putchar('M') == EOF || putchar('-') == EOF)
					break;
				wch = toascii(wch);
			}
			if (iswcntrl(wch)) {
				ch = toascii(wch);
				ch = (ch == '\177') ? '?' : (ch | 0100);
				if (putchar('^') == EOF || putchar(ch) == EOF)
					break;
				continue;
			}
			if (putwchar(wch) == WEOF)
				break;
			ch = -1;
			continue;
		}
		if (putchar(ch) == EOF)
			break;
	}
	if (ferror(fp)) {
		warn("%s", filename);
		rval = 1;
		clearerr(fp);
	}
	if (ferror(stdout))
		err(1, "stdout");
}
Exemplo n.º 9
0
bool VariantToString(const VARIANT* pvd, BL_IEC_TYP want, FC_CString* pJot, bool bForDisplay)
{
    HRESULT        hr;
    VARIANT        tmp;
    wchar_t        buffer[2*MAX_PATH];
    const wchar_t* pszw;

    pJot->clear();

    if(pvd->vt==VT_EMPTY)
        return false;


    if((want==BL_STRING || want==BL_WSTRING))
    {
        if(pvd->vt == VT_BSTR)
        {
            pszw = pvd->bstrVal;
            hr = S_OK;
        }
        else
        {
            VariantInit(&tmp);
            hr = VariantChangeType(&tmp, (VARIANT*)pvd, VARIANT_NOVALUEPROP, VT_BSTR);
                return false;
            pszw = tmp.bstrVal;
        }
        
        if(SUCCEEDED(hr))
        {
            if(bForDisplay)
            {
                int            i;
                wchar_t        tmp[2];
                const wchar_t* psz;
                
                tmp[1] = 0;
                pJot->addc(want==BL_STRING? _T('\'') : _T('"'));
                
                for(i=0,psz=pszw; *psz && i<64; psz++,i++)
                {
                    tmp[0] = *psz; 
                    if(i>64)
                    {
                        (*pJot)<<_T("  ...");
                        break;
                    }
                    else if(iswprint(*psz) && iswascii(*psz))
                    {
                        (*pJot)<<tmp;
                    }
                    else
                    {
                        pJot->addc(_T('?'));
                    }
                }

                if(*psz==0)
                    pJot->addc(want==BL_STRING? _T('\'') : _T('"'));
            }
            else
            {
                //TODO  embedded 0-chars ? 
                pJot->load(pszw);
            }

            if(pvd->vt != VT_BSTR)
                VariantClear(&tmp);
        }
    }
    else
    {
        //DWORD fmt = bForDisplay ? BL_USE_IEC_FORMAT|BL_USE_TYPED_LITERALS : BL_USE_IEC_FORMAT;
        //TODO BL_USE_TYPED_LITERALS does not work??
        hr = BL_VariantToString((VARIANT*)pvd, want, NULL, BL_USE_IEC_FORMAT, buffer, FC_ARRAY_LEN(buffer));
        if(SUCCEEDED(hr))
        {
            if(bForDisplay && want!=BL_BOOL && !wcschr(buffer, _T('#')))//HACK
                pJot->load(BLTypToString(want))<<_T("#");
            
            (*pJot)<<buffer;
            pJot->toLower();
        }
    }

    return hr == S_OK;
}