PDA

View Full Version : نیاز به تابع تبدیل رشته به UTF-8 در دلفی 7



arkia
سه شنبه 03 مرداد 1391, 17:29 عصر
سلام و خسته نباشید،
من برای ارسال متن فارسی به یک وب سرویس به تابعی نیاز دارم که String فارسی توی دلفی 7 رو تبدیل کنه به utf8 این رو پیدا کردم (http://fundementals.sourceforge.net/unicode.html) اما نتونستم ازش جواب بگیرم، پیشاپیش از راهنمایی هاتون ممنونم

tdkhakpur
سه شنبه 03 مرداد 1391, 18:43 عصر
سلام و خسته نباشید،
من برای ارسال متن فارسی به یک وب سرویس به تابعی نیاز دارم که String فارسی توی دلفی 7 رو تبدیل کنه به utf8 این رو پیدا کردم (http://fundementals.sourceforge.net/unicode.html) اما نتونستم ازش جواب بگیرم، پیشاپیش از راهنمایی هاتون ممنونم
خود دلفی 7 متن رو utf8 ثبت میکنه واسه چی میخای تبدیل کنی؟

arkia
سه شنبه 03 مرداد 1391, 23:17 عصر
وقتی به وب سرویس رشته فارسی ارسال می کنم ، وب سرویس متن رو به صورت علامت سوال دریافت میکنه. فکر کنم دلیلش اینه که دلفی 7 از یونیکد پشتیبانی نمیکنه...
از برنامه نویس اون وب سرویس پرسیدم گفت متغیر های من یونیکده...
دلفی دو تا تابع داره اونا هم جواب نداد:

ansitoutf8()
و
Utf8Encode()

tdkhakpur
چهارشنبه 04 مرداد 1391, 10: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, 11:28 صبح
کلا علامت 8 بایت حساب میشه باید دنبال 16 میرفتید.
الان دلفی دم دستم نیست اما این راهنما رو نگاه کن

Syntax
int ToUnicode( UINT wVirtKey, UINT wScanCode, const PBYTE lpKeyState, LPWSTR pwszBuff, int cchBuff, UINT wFlags );

پارامتر هاشو چی بزارم؟

arkia
چهارشنبه 04 مرداد 1391, 11:40 صبح
رفرنسشو از مایکروسافت پیدا کردم اما بازم نمیدونم این چیزا که میخواد چیه
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646320(v=vs.85).aspx

tdkhakpur
چهارشنبه 04 مرداد 1391, 14: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, 19: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, 20:54 عصر
اما من برعکس اینو میخوام یعنی ANSI STRING TO UNICODEداداش شما مسئله رو خیلی پیچیده گرفتی!
اون تابع ارسالی متن ansi رو میگیره و به رشته گسترده یا همون unicode خودمان تبدیل میکنه.
محتوای رشته خروجی رو بعد تبدیل نگا کن هر کدوم از کاراکتر های ارسالی شما تبدیل به دو بایت شده و طول حافظه گرفته شده دو برابر رشته اولی شماست.

Ananas
چهارشنبه 04 مرداد 1391, 22: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, 14:17 عصر
دوستان هنوز جواب نگرفتم
من دارم تو دلفی 7 از یک وب سرویس استفاده می کنم که خود این وب سرویس کاراکتر های فارسی غیر utf8 رو تبدیل به علامت سوال میکنه اما وقتی از این وب سرویس تو دلفی XE استفاده می کنم مشکلی پیش نمیاد.