View Full Version : نیاز به تابع تبدیل رشته به UTF-8 در دلفی 7
  
arkia
سه شنبه 03 مرداد 1391, 18:29 عصر
سلام و خسته نباشید،
من برای ارسال متن فارسی به یک وب سرویس به تابعی نیاز دارم که String فارسی توی دلفی 7 رو تبدیل کنه به utf8 این رو پیدا کردم (http://fundementals.sourceforge.net/unicode.html) اما نتونستم ازش جواب بگیرم، پیشاپیش از راهنمایی هاتون ممنونم
tdkhakpur
سه شنبه 03 مرداد 1391, 19:43 عصر
سلام و خسته نباشید،
من برای ارسال متن فارسی به یک وب سرویس به تابعی نیاز دارم که String فارسی توی دلفی 7 رو تبدیل کنه به utf8 این رو پیدا کردم (http://fundementals.sourceforge.net/unicode.html) اما نتونستم ازش جواب بگیرم، پیشاپیش از راهنمایی هاتون ممنونم
 خود دلفی 7 متن رو utf8 ثبت میکنه واسه چی میخای تبدیل کنی؟
arkia
چهارشنبه 04 مرداد 1391, 00:17 صبح
وقتی به وب سرویس رشته فارسی ارسال می کنم ، وب سرویس متن رو به صورت علامت سوال دریافت میکنه. فکر کنم دلیلش اینه که دلفی 7 از یونیکد پشتیبانی نمیکنه... 
از برنامه نویس اون وب سرویس پرسیدم گفت متغیر های من یونیکده...
دلفی دو تا تابع داره اونا هم جواب نداد:
ansitoutf8()
و
 Utf8Encode()
tdkhakpur
چهارشنبه 04 مرداد 1391, 11:34 صبح
کلا علامت 8 بایت حساب میشه باید دنبال 16 میرفتید.
الان دلفی دم دستم نیست اما این راهنما رو نگاه کن
Syntax
int ToUnicode( UINT wVirtKey, UINT wScanCode, const PBYTE lpKeyState, LPWSTR pwszBuff, int cchBuff, UINT wFlags );
The ToUnicode function translates the specified virtual-key code and  keyboard state to the corresponding Unicode character or characters.  
To specify a handle to the keyboard layout to use to translate the specified  code, use the ToUnicodeEx function.
  
Parameters
 wVirtKey [in] Specifies the virtual-key code to be translated. wScanCode [in] Specifies the hardware scan code of the key to be translated. The  high-order bit of this value is set if the key is up. lpKeyState [in] Pointer to a 256-byte array that contains the current keyboard state.  Each element (byte) in the array contains the state of one key. If the  high-order bit of a byte is set, the key is down. pwszBuff [out] Pointer to the buffer that receives the translated Unicode character  or characters. However, this buffer may be returned without being  null-terminated even though the variable name suggests that it is  null-terminated. cchBuff [in] Specifies the size, in wide characters, of the buffer pointed to by the  pwszBuff parameter. wFlags [in] Specifies the behavior of the function. If bit 0 is set, a menu is  active. Bits 1 through 31 are reserved.Return Value
 The function returns one of the following values.
    -1 The specified virtual key is a dead-key character (accent or diacritic).  This value is returned regardless of the keyboard layout, even if several  characters have been typed and are stored in the keyboard state. If possible,  even with Unicode keyboard layouts, the function has written a spacing version  of the dead-key character to the buffer specified by pwszBuff. For  example, the function writes the character SPACING ACUTE (0x00B4), rather than  the character NON_SPACING ACUTE (0x0301).  0 The specified virtual key has no translation for the current state of the  keyboard. Nothing was written to the buffer specified by  pwszBuff.  1 One character was written to the buffer specified by  pwszBuff.  2 or more Two or more characters were written to the buffer specified by  pwszBuff. The most common cause for this is that a dead-key character  (accent or diacritic) stored in the keyboard layout could not be combined with  the specified virtual key to form a single character. However, the buffer may  contain more characters than the return value specifies. When this happens, any  extra characters are invalid and should be  ignored.
Remarks
 The parameters supplied to the ToUnicode function might not be  sufficient to translate the virtual-key code because a previous dead key is  stored in the keyboard layout.
 Typically, ToUnicode performs the translation based on the virtual-key  code. In some cases, however, bit 15 of the wScanCode parameter can be  used to distinguish between a key press and a key release.
Function Information
arkia
چهارشنبه 04 مرداد 1391, 12:28 عصر
کلا علامت 8 بایت حساب میشه باید دنبال 16 میرفتید.
الان دلفی دم دستم نیست اما این راهنما رو نگاه کن
Syntax
int ToUnicode( UINT wVirtKey, UINT wScanCode, const PBYTE lpKeyState, LPWSTR pwszBuff, int cchBuff, UINT wFlags );
 
پارامتر هاشو چی بزارم؟
arkia
چهارشنبه 04 مرداد 1391, 12:40 عصر
رفرنسشو از مایکروسافت پیدا کردم اما بازم نمیدونم این چیزا که میخواد چیه
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646320(v=vs.85).aspx
tdkhakpur
چهارشنبه 04 مرداد 1391, 15:25 عصر
پارامتر هاشو چی بزارم؟
تابع زیر رو استفاده کن
:Converts Unicode string to Ansi string using specified code page.
function StringToWideString(const s: AnsiString; codePage: Word): WideString;
var
  l: integer;
begin
  if s = ' then
    Result := '
  else 
  begin
    l := MultiByteToWideChar(codePage, MB_PRECOMPOSED, PChar(@s[1]), - 1, nil, 0);
    SetLength(Result, l - 1);
    if l > 1 then
      MultiByteToWideChar(CodePage, MB_PRECOMPOSED, PChar(@s[1]),
        - 1, PWideChar(@Result[1]), l - 1);
  end;
end; { StringToWideString }
مثال
procedure TForm1.Button1Click(Sender: TObject);
var
  str : WideString;
  s:string;
  k:integer;
begin
 s:='س';
 k := integer(s[1]);
 ShowMessage(String('non unicode is ')+IntToStr(k));
 str := ToUnicodeString('س');
 ShowMessage(String('unicode is ')+IntTostr(integer(str[1])) );
end;
end.
arkia
چهارشنبه 04 مرداد 1391, 20:51 عصر
تابع زیر رو استفاده کن
:Converts Unicode string to Ansi string using specified code page.
 
ممنون . اما من برعکس اینو میخوام یعنی ANSI STRING TO UNICODE
تابع زیر رو استفاده کن
function StringToWideString(const s: AnsiString; codePage: Word): WideString;
var
  l: integer;
begin
  if s = ' then
    Result := '
  else 
  begin
    l := MultiByteToWideChar(codePage, MB_PRECOMPOSED, PChar(@s[1]), - 1, nil, 0);
    SetLength(Result, l - 1);
    if l > 1 then
      MultiByteToWideChar(CodePage, MB_PRECOMPOSED, PChar(@s[1]),
        - 1, PWideChar(@Result[1]), l - 1);
  end;
end; { StringToWideString }[/PASCAL]
[/PASCAL]
 
کار این تابع هم متوجه نشدم برا چیه 
تابع زیر رو استفاده کن
مثال
procedure TForm1.Button1Click(Sender: TObject);
var
  str : WideString;
  s:string;
  k:integer;
begin
 s:='س';
 k := integer(s[1]);
 ShowMessage(String('non unicode is ')+IntToStr(k));
 str := ToUnicodeString('س');
 ShowMessage(String('unicode is ')+IntTostr(integer(str[1])) );
end;
end.
  
این قسمت بیشتر به هدف من نزدیکه اما تابعی به اسم ToUnicodeString نداره به جاش ToUnicode داره که پارامتر های زیادی داره ازشون هم سر در نیاوردم که ورودی چی بدم بهش.
tdkhakpur
چهارشنبه 04 مرداد 1391, 21:54 عصر
اما من برعکس اینو میخوام یعنی ANSI STRING TO UNICODEداداش شما مسئله رو خیلی پیچیده گرفتی!
اون تابع ارسالی متن ansi رو میگیره و به رشته گسترده یا همون unicode خودمان تبدیل میکنه.
محتوای رشته خروجی رو بعد تبدیل نگا کن هر کدوم از کاراکتر های ارسالی شما تبدیل به دو بایت شده و طول حافظه گرفته شده دو برابر رشته اولی شماست.
Ananas
چهارشنبه 04 مرداد 1391, 23:27 عصر
سلام.
خودتونم می تونید این تابع رو بنویسید :
function Str8ToStr16(const ansiStr : PAnsiChar):PWideChar;
var
  pch : PAnsiChar;
  pwch : PWideChar;
begin
  // find end of string
  pch := ansiStr;
  while ((PByte(pch))^ <> 0) do
    Inc(pch);
  Result := AllocMem( (UInt64(pch) - UInt64(ansiStr) + 1) * 2 ); // SizeOf(WideChar) == 2
  // ----------------
  // copy 8-bit char's to 16`-bit char's
  pwch := Result;
  pch := ansiStr;
  while ((PByte(pch))^ <> 0) do
  begin
    pwch^ := WideChar(pch^); // convert AnsiChar to WideChar
    Inc(pwch);
    Inc(pch);
  end;
  // ----------------
  pwch^ := WideChar(0); // set end of string to NULL
end;
function Str16ToStr8(const wideStr : PWideChar):PAnsiChar;
var
  pch : PAnsiChar;
  pwch : PWideChar;
begin
  // find end of string
  pwch := wideStr;
  while ((PWord(pwch))^ <> 0) do
    Inc(pwch);
  // ----------------
  Result := AllocMem( (UInt64(pwch) - UInt64(wideStr) + 1) div 2 );
  // ----------------
  // copy 16-bit char's to 8-bit char's
  pch := Result;
  pwch := wideStr;
  while ((PWord(pwch))^ <> 0) do
  begin
    pch^ := AnsiChar(pwch^); // convert WideChar to AnsiChar
    Inc(pwch);
    Inc(pch);
  end;
  // ----------------
  pch^ := AnsiChar(0);  // set end of string to NULL
end;
چند تا نکته رو باید رعایت کنید :
1 - حافظه ی مورد نیاز حتما باید اختصاص داده بشه و یا موجود باشه که بخواید تغییر بدید.
2 - تبدیل 8 بیت به 16 بیت و یا بر عکس، برای هر کاراکتر باید انجام بشه (دونه به دونه).
3 - انتهای رشته باید با کاراکتر 0 (NULL) مقدار دهی بشه. که موقع تخصیص حافظه هم باید یک واحد اضافه برای کاراکتر آخر (NULL) حافظه بگیرید.
arkia
یک شنبه 09 مهر 1391, 15:17 عصر
دوستان هنوز جواب نگرفتم
من دارم تو دلفی 7 از یک وب سرویس استفاده می کنم که خود این وب سرویس کاراکتر های فارسی غیر utf8 رو تبدیل به علامت سوال میکنه اما وقتی از این وب سرویس تو دلفی XE استفاده می کنم مشکلی پیش نمیاد.
 
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.