PDA

View Full Version : سوال: ارسال رشته يونيكد بوسيله sendmessage



tdkhakpur
چهارشنبه 25 خرداد 1390, 10:34 صبح
سلام داخل راهنماي دلفي 2009 به بعد براي ارسال يك رشته كه يونيكد هست با wm_settext نميشه چيزي وجود نداره گزينه ديگه وجود داره كه به جاي wm_settext استفاده بشه.
ممنون

vcldeveloper
چهارشنبه 25 خرداد 1390, 12:34 عصر
با wm_settext نميشه چيزي وجود نداره
نمیشه یعنی چی؟ توضیح بدید که چه کدی نوشتید، و با چه مشکلی برخورد کردید.

مشکلی در استفاده از WM_SETTEXT با کارکترهای یونیکد نیست:


var
Str : string;
begin
Str := 'این یک تست است';
SendMessage(Edit1.Handle, WM_SETTEXT, 0, Integer(PChar(Str)));
end;

tdkhakpur
چهارشنبه 25 خرداد 1390, 19:56 عصر
نمیشه یعنی چی؟ توضیح بدید که چه کدی نوشتید، و با چه مشکلی برخورد کردید.
من که بالا گفتم متن یک رشته از نوع یونیکد هست نه char
شما همون string رو از نوع WideString بگیرید و ارسال کنید نتیجه کاراکترهایی هست که WM_SETTEXT مربوط به کنترل نمیتونه تشخیص بده و متن رو به درستی نشون بده.

Felony
چهارشنبه 25 خرداد 1390, 20:13 عصر
یعنی این کد ؟ :

var
Str : WideString;
begin
Str := 'این یک تست است';
SendMessage(Edit1.Handle, WM_SETTEXT, 0, Integer(PChar(Str)));
end;

مشکلی نداره !

tdkhakpur
پنج شنبه 26 خرداد 1390, 01:11 صبح
مشکلی نداره !

چی مشکل نداره؟
پارامترهای sendmessage برای wm_settext این رو نشون میده که شما داده رو بصورت char ارسال میکنید یعنی داده بصورت widechar نیست به همین دلیل توی مقصد داده ها به همان صورتی که باید برسه نیست و char بوده و نتیجه نمایش اشتباه از آب در میاد.
در کل به چه عنوانی پیغام ارسال بشه تا داده رو بصورت یونیکد تشخیص بده؟

Mahmood_M
پنج شنبه 26 خرداد 1390, 01:58 صبح
اگر از نسخه های قبل از 2009 دلفی استفاده میکنید ، برای حل مشکلتون باید متنتون رو Encode کنید به UTF-8 و بعد متن Encode شده رو به نوع AnsiString تبدیل و ارسال کنید ، مثال :

var
Str : UTF8String;
begin
Str := UTF8Encode('این یک تست است');
SendMessage(Edit1.Handle, WM_SETTEXT, 0, Integer(Utf8ToAnsi(Str)));
end;

این کد در دلفی 7 بدون مشکل عمل میکنه
البته توجه کنید که قسمت Script برای فونت Edit ( گیرنده ی متن ) روی Arabic تنظیم شده باشه ، وگر نه کارکترهای ناخوانا نمایش داده میشن

اگر باز هم مشکلی وجود داشت ، جزئیات بیشتری از برنامتون بگید ( نسخه ی دلفی ، نوع های String ای که استفاده می کنید ، نوع TypeCast و ... )

موفق باشید ...

tdkhakpur
پنج شنبه 26 خرداد 1390, 10:22 صبح
اگر باز هم مشکلی وجود داشت ، جزئیات بیشتری از برنامتون بگید
مشکلی در نوع تبدیل و یا تغییر برای نمایش نیست مقصود اینه که داده های یونیکد شده رو به یک edit توسط sendmesage بفرستم و این داده دو بایتی و از نوع WideString هست. اگر تبدیل به utf8 بشه به این معنی هست اصل داده تغییر میکنه و نباید به تغیر صورت بگیره.
قصدم از این کار طراحی یک برنامه فارسی ساز مستقل از ویندوز برای کل ویندوز هست.

vcldeveloper
شنبه 28 خرداد 1390, 21:52 عصر
چی مشکل نداره؟
پارامترهای sendmessage برای wm_settext این رو نشون میده که شما داده رو بصورت char ارسال میکنید یعنی داده بصورت widechar نیست به همین دلیل توی مقصد داده ها به همان صورتی که باید برسه نیست و char بوده و نتیجه نمایش اشتباه از آب در میاد.
برداشت شما اشتباه هست؛ سوال شما میگه شما دارید از دلفی 2009 استفاده می کنید، وقتی میگید دلفی 2009، یعنی:

string = UnicodeString
Char = WideChar
PChar = PWideChar
SendMessage = SendMessageW

در دلفی 2009، نوع داده WideString کاربرد خاصی (به جز استفاده در COM) نداره، چون کارایی اش از نوع داده اختصاصی UnicodeString (که همون نوع string هست) بسیار پایین تر هست.

پس کدی که در پست شماره 2 نوشتم، کاملا با یونیکد سازگار هست، و رشته را هم به صورت یونیکد (UTF-16 LE) به مقصد ارسال میکنه. اگر اون کد برای شما کار نمیکنه، مشکل شما از جای دیگه است، و از اونجایی که هنوز توضیح ندادید که منظور شما از "نمیشه" چیه، و معلوم نیست در سمت گیرنده پیام اصلا چه رفتاری صورت میگیره، اصلا گیرنده کی هست؟ یونیکد هست یا نه؟ خودتون کدش را نوشتید یا نه؟ و سایر موارد، نمیشه اینطوری کمک خاصی به شما کرد.

tdkhakpur
یک شنبه 29 خرداد 1390, 11:23 صبح
پس کدی که در پست شماره 2 نوشتم، کاملا با یونیکد سازگار هست، و رشته را هم به صورت یونیکد (UTF-16 LE) به مقصد ارسال میکنه. اگر اون کد برای شما کار نمیکنه، مشکل شما از جای دیگه است، و از اونجایی که هنوز توضیح ندادید که منظور شما از "نمیشه" چیه، و معلوم نیست در سمت گیرنده پیام اصلا چه رفتاری صورت میگیره، اصلا گیرنده کی هست؟ یونیکد هست یا نه؟

wm_settext یک از پارامترهای api هست و اگه به راهنمای دلفی نگاه کنید دو پارامتر دیگه لازم داره تا داده رو ارسال کنه و این داده باید از نوع chr باشند.
درسته کدی که شما نوشتید درست کار میکنه ولی اگه script فونت از عربی به لاتین تغییر کنه اونوقت داده ها درست در نشون داده نمیشن در ضمن شما اول کار داده ها رو به اسکی تبدیل میکنید و کار تبدیل به یونیکد رو به خود کنترل واگذار کرده اید(script) و احتیاجی به بررسی مقصد نداره.

خودتون کدش را نوشتید یا نه؟ و سایر موارد، نمیشه اینطوری کمک خاصی به شما کرد
کد زیادی لازم نیست شما اون بالا نوشتید و من به همون روش کار میکردم فقط موضوع اینه که من یک گزینه مثل wm_setunicodetext لازم دارم چون مقصد داده ها رو بصورت یونیکد میگیره.
ان که گفتید Char = WideChar رو یک بار با sizeof اندازه بگیرید ببینید مساوی هستن یا نه. برای من که نیست.(البته اگر هم باشن فرقی به حال sendmessage چون شما داخل کد ارسالی تان pchar کرده اید. )


var
Str : string;
begin
Str := 'این یک تست است';
SendMessage(Edit1.Handle, WM_SETTEXT, 0, Integer(PChar(Str)));
end;

vcldeveloper
یک شنبه 29 خرداد 1390, 21:01 عصر
در ضمن شما اول کار داده ها رو به اسکی تبدیل میکنید و کار تبدیل به یونیکد رو به خود کنترل واگذار کرده اید
wm_settext یک از پارامترهای api هست و اگه به راهنمای دلفی نگاه کنید دو پارامتر دیگه لازم داره تا داده رو ارسال کنه و این داده باید از نوع chr باشند.
ان که گفتید Char = WideChar رو یک بار با sizeof اندازه بگیرید ببینید مساوی هستن یا نه. برای من که نیست.(البته اگر هم باشن فرقی به حال sendmessage چون شما داخل کد ارسالی تان pchar کرده اید. )نمیدونم چرا اصرار دارید درباره چیزی که ازش اطلاع ندارید، اظهار نظر کنید!

دوست عزیز، بخش عمده API های ویندوز دو نسخه ANSI و Unicode دارند. ویندوز خودش به طور داخلی فقط از یونیکد با استاندارد UTF-16 استفاده میکنه؛ یعنی حتی توابع ANSI ویندوز هم متن ANSI دریافتی رو به UTF-16 تبدیل می کنند و سپس به طور داخلی تابع یونیکد مربوطه رو اجرا می کنند.

پس وقتی شما میخواید با یونیکد در ویندوز کار کنید، باید اول از همه بدونید که باید نسخه یونیکد یک تابع API رو اجرا کنید، نه نسخه ANSI اون رو. نسخه یونیکد SendMessage اسمش هست: SendMessageW. پس باید SednMessageW رو فراخوانی کنید. تا اینجاش رو متوجه شدید؟

حالا، حتما شنیدید که میگن دلفی 2009 یونیکد هست، بله؟ وقتی میگن یونیکد هست یعنی چی؟ یعنی اگر شما برید تعریف یک تابع مثل SendMessage رو ببینید، به کدی مثل این میرسید:


function SendMessage; external user32 name 'SendMessageW';
یعنی چی؟ یعنی SendMessage در دلفی 2009 و نسخه های بعدی اون، معادل SendMessageW ویندوز هست. پس وقتی می نویسید SendMessage یعنی دارید SendMessageW را فراخوانی می کنید. در دلفی 7 این تعریف به چه شکلی بود؟ به این صورت:

function SendMessage; external user32 name 'SendMessageA';

یعنی چی؟ یعنی در دلفی 7 اگر می نوشتید SendMessage، در واقع داشتید SendMessageA رو فراخوانی می کردید که نسخه ANSI تابع SendMessage هست.

این رو تا اینجا متوجه شدید؟

حالا می رسیم به نوع های داده دلفی؛ در دلفی نوع های داده ایی مثل string, PChar, Char و امثالهم نوع داده Alias هستند. Alias یعنی چی؟ یعنی فقط یک نام برای یک نوع داده دیگه هستند. حالا برای اینکه بفهمید هر کدوم از این نوع های داده در یک نسخه از دلفی به چه نوع داده ایی map میشند، تشریف می برید به یونیت System و این بخش از کد رو می بینید:


{$IFDEF UNICODE}
{$EXTERNALSYM AnsiChar 'char' } {$OBJTYPENAME AnsiChar 'Bc'}
{$IFDEF LINUX}
{$NODEFINE Char 'WideChar' } {$OBJTYPENAME Char 'Bus'} { unsigned short }
{-OBJTYPENAME Char 'BCs'} { char16_t }
{$ELSE}
{$NODEFINE Char 'WideChar' } {$OBJTYPENAME Char 'Bb'} { wchar_t }
{-OBJTYPENAME Char 'BCs'} { char16_t }
{$ENDIF}
{$NODEFINE string 'UnicodeString' } {$OBJTYPENAME string 'NUnicodeString'} { defined in vcl/ustring.h }
{-NODEFINE string 'String' } {$OBJTYPENAME string 'NUnicodeString'} { defined in vcl/ustring.h }
{$NODEFINE AnsiString } { defined in vcl/dstring.h }
{$NODEFINE WideString } { defined in vcl/wstring.h }
{$NODEFINE PChar } { alias of PWideChar }
{$NODEFINE WideChar } { alias of Char }
{$NODEFINE UnicodeString} { alias of string }
{$ELSE}
{$EXTERNALSYM Char 'char' } {$OBJTYPENAME Char 'Bc'}
{$IFDEF LINUX}
{$NODEFINE WideChar 'WideChar' } {$OBJTYPENAME WideChar 'Bus'} { unsigned short }
{-OBJTYPENAME WideChar 'BCs'} { char16_t }
{$ELSE}
{$NODEFINE WideChar 'WideChar' } {$OBJTYPENAME WideChar 'Bb'} { wchar_t }
{-OBJTYPENAME WideChar 'BCs'} { char16_t }
{$ENDIF}
{$NODEFINE string 'AnsiString' } { defined in vcl/dstring.h }
{-NODEFINE string 'String' } { defined in vcl/dstring.h }
{$NODEFINE WideString } { defined in vcl/wstring.h }
{$NODEFINE UnicodeString} { defined in vcl/ustring.h }
{$NODEFINE PChar } { alias of PAnsiChar }
{$NODEFINE AnsiChar } { alias of Char }
{$NODEFINE AnsiString } { alias of string }
{$ENDIF}


این کد چیه؟ این بخشی از تعریف نوع های داده پایه دلفی هست. همونطور که در کد هم مشخص هست، اینطور تعریف شده که اگر کامپایلر یونیکد هست (یعنی دلفی 2009و 2010و XE)، در اون صورت برای ویندوز:

string = UnicodeString
PChar = PWideChar
Char = WideChar

باشه، و اگر یونیکد نیست (دلفی 2007 و تمامی نسخه های قبل از آن) برای ویندوز:

string = AnsiString
PChar = PAnsiChar
Char = AnsiChar

باشه.

پس چی شد؟ وقتی جنابعالی دارید از دلفی 2009 استفاده می کنید، string شما یونیکد هست! PChar شما هم به PWideChar مپ میشه، و یونیکد هست. SendMessage شما هم یونیکد هست. برای همین نیازی نیست که من بنویسم Str : WideString، بلکه می نویسم Str : String؛ چرا؟ چون String = UnicodeString پس کد من میشه Str : UnicodeString. نیازی نیست من بنویسم PWideChar، چرا؟ چون PChar = PWideChar هست.

حالا چرا از Alias استفاده میشه، نه از نوع واقعی داده ها؟ برای سازگاری کد؛ برای اینکه شما بتونید یک سورس کد از نسخه های قدیمی را راحتر در نسخه های جدید کامپایل کنید. برای اینکه بتونید یک کد بنویسید که بدون مشکل هم در نسخه های قدیمی و هم در نسخه های جدید کار کنه.

پس نتیجه این همه توضیحات چی میشه؟ اینکه اولا ادعای شما مبنی بر:


در ضمن شما اول کار داده ها رو به اسکی تبدیل میکنید و کار تبدیل به یونیکد رو به خود کنترل واگذار کرده ایدادعای غلطی هست، چون در اون کد هیچگونه تبدیل ضمنی یا غیر ضمنی صورت نمیگیره؛ string دلفی UTF-16 هست، ویندوز هم با UTF-16 کار میکنه، PChar هم به یک کارکتر UTF-16 اشاره میکنه؛ پس نیازی به تبدیل داده ها نیست.

ثانیا، برداشت شما مبنی بر :


فقط موضوع اینه که من یک گزینه مثل wm_setunicodetext لازم دارم چون مقصد داده ها رو بصورت یونیکد میگیره.
غلط هست، چون WM_SETTEXT به طور پیش فرض به صورت یونیکد عمل میکنه، مگر اینکه شما از تابع SendMessageA استفاده کنید.

ثالثا؛ ادعای دیگه شما مبنی بر:


این که گفتید Char = WideChar رو یک بار با sizeof اندازه بگیرید ببینید مساوی هستن یا نه. برای من که نیست.(البته اگر هم باشن فرقی به حال sendmessage چون شما داخل کد ارسالی تان pchar کرده اید. )غلط هست، چون همانطور که در بالا توضیح دادم، در دلفی 2009، PChar = PWideChar هست. برای بررسی اندازه این نوع های داده هم می تونید از کد زیر استفاده کنید:



var
Msg : string;
begin
Msg := Format('AnsiChar = %d, WideChar = %d, Char = %d',
[SizeOf(AnsiChar), SizeOf(WideChar), SizeOf(Char)]);
ShowMessage(Msg);
end;

که نتیجه اجرای این کد در دلفی 2009، دلفی 2010، و دلفی XE میشه:

AnsiChar = 1, WideChar = 2, Char = 2

و در دلفی 7 میشه:

AnsiChar = 1, WideChar = 2, Char = 1

پس در دلفی 2009 و نسخه های جدیدتر، اندازه Char = 2 بایت هست، که نشانه یونیکد بودن اون هست. همچنین می تونید به راهنمای دلفی درباره Char مراجعه کنید که نوشته:

Char is the equivalent of the WideChar (http://barnamenevis.org/System.WideChar.html) type (because the default string type is UnicodeString (http://barnamenevis.org/System.UnicodeString.html)).

این هم لینکش:
http://docwiki.embarcadero.com/VCL/e/index.php/System.Char

و مورد آخر اینکه، حرف شما مبنی بر:


ولی اگه script فونت از عربی به لاتین تغییر کنه اونوقت داده ها درست در نشون داده نمیشنبی ربط به یونیکد هست! یونیکد یک استاندارد ذخیره متن هست، نه استاندارد نمایش متن. یونیکد میگه متن شما در حافظه چطور نمایش داده بشه. اینکه یک فونت با تغییر script اش نمیتونه کارکتری رو نمایش بده، ربطی به یونیکد یا داده ارسالی نداره؛ اگر شما یک فونت غیر یونیکد داشته باشید، یا فونت شما به هر دلیلی مشکلی داشته باشه، دلیلی نمیشه که داده یونیکد ارسالی درست نمایش داده بشه؛ پس عدم نمایش صحیح یک فونت ربطی به ارسال صحیح یک داده یونیکد نداره.


من دیگه نمیتونم از این واضح تر و روشن تر توضیح بدم!

tdkhakpur
دوشنبه 30 خرداد 1390, 01:10 صبح
من دیگه نمیتونم از این واضح تر و روشن تر توضیح بدم!

جناب کشاورز من نظرم از این پست اینه که مشکلی که دارم رو حل کنم مسابقه که نمیدیم!!
اون مطالبی که شما ارسال کردید مشکل بنده رو حل نمیکنه من راحتتر بگم خودتان هم امتحان کنید دو دانه edit رو فرمتان قرار بدید(دلفی 2009 به بعد ) و با sendmessage محتوای edit1 رو بصورت زیر به ادیت دو انتقال بدید.


sendmessage(Edit2.Handle, wm_settext, Edit1.Text);

اون قسمت قرمز رنگ شده رو به چه نحو باید ارسال کرد تا یونیکد text ارسال بشه.

vcldeveloper
دوشنبه 30 خرداد 1390, 03:49 صبح
اون مطالبی که شما ارسال کردید مشکل بنده رو حل نمیکنه من راحتتر بگم خودتان هم امتحان کنیدبنده هم نگفتم مشکل شما رو حل میکنه، بلکه گفتم، مشکل شما از جای دیگه است، و ارسال متن یونیکد به شکلی که در پست 2 نوشتم، مشکلی نداره، و نیازی نیست شما دنبال یک نسخه ویژه از WM_SETTEXT باشید.



خودتان هم امتحان کنید دو دانه edit رو فرمتان قرار بدید(دلفی 2009 به بعد ) و با sendmessage محتوای edit1 رو بصورت زیر به ادیت دو انتقال بدید.محتویات یک Edit به اون شکل پاس نمیشه، بلکه باید ابتدا به PChar اون رو Type-cast کنید و سپس به integer؛ همون کاری که در پست شماره 2 انجام دادم. اون وقت می بینید که بدون مشکل کار میکنه:


SendMessage(Edit2.Handle, WM_SETTEXT, 0, Integer(PChar(Edit1.Text)));

tdkhakpur
سه شنبه 31 خرداد 1390, 22:21 عصر
این همه توضیح دادید خلاصه میگفتید از sendmessagew استفاده کنید بهتر میشد من هم دنبال همین بودم.

vcldeveloper
چهارشنبه 01 تیر 1390, 00:58 صبح
این همه توضیح دادید خلاصه میگفتید از sendmessagew استفاده کنید بهتر میشد من هم دنبال همین بودم.
این همه توضیح دادم که شما متوجه بشید در دلفی 2009 تابع SendMessage = SendMessageW!

tdkhakpur
چهارشنبه 01 تیر 1390, 08:29 صبح
در دلفی 2009 تابع SendMessage = SendMessageW!
نباید مساوی باشه اما به اجبار مساوی شده.

function SendMessage; external user32 name 'SendMessageW';

در ضمن اونایی که مثل ما احتیاج به یونیکد ندارن(لاتین زبانها) چی؟ sendmessage قبلی رو که با اسکی کار میکنه درو بندازن؟

vcldeveloper
چهارشنبه 01 تیر 1390, 11:57 صبح
نباید مساوی باشه اما به اجبار مساوی شده.
بازم شد از اون حرفها!!!

SendMessage در کل سیستم عامل ویندوز به طور پیش فرض مساوی هست با SendMessageW؛ چون سیستم عامل ویندوز یونیکد هست. پس SendMessage = SendMessageW پیش فرض ویندوز هست. لطفا از این مدل اظهار نظرهای غیر فنی و غیر کارشناسی نکنید.


در ضمن اونایی که مثل ما احتیاج به یونیکد ندارن(لاتین زبانها) چی؟ sendmessage قبلی رو که با اسکی کار میکنه درو بندازن؟
اولا بهتره که همچنان از همون نسخه یونیکد تابع مربوطه استفاده کنند، چون استفاده از نسخه ANSI مزیتی براشون بوجود نمیاره (یک بار توضیح دادم که ویندوز در ساختارهای داخلی خودش فقط با یونیکد کار میکنه، پس داده های ANSI هم نهایتا تبدیل به یونیکد میشند، سپس در زمان آماده شدن خروجی یک تابع، خروجی دوباره به ANSI تبدیل میشه).
حالا بر فرض اگر کسی واقعا مجبور باشه که با داده ANSI کار کنه، می تونه از نسخه ANSI اون تابع یعنی SendMessageA استفاده کنه.

tdkhakpur
پنج شنبه 02 تیر 1390, 00:58 صبح
در کل سیستم عامل ویندوز به طور پیش فرض مساوی هست با SendMessageW؛ چون سیستم عامل ویندوز یونیکد هست. پس SendMessage = SendMessageW پیش فرض ویندوز هست. لطفا از این مدل اظهار نظرهای غیر فنی و غیر کارشناسی نکنید.


خسته نباشی!
اینطور نیست اونوقت چه لزومی داشت این همه دادو بیداد بشه که کامپایلرهای اومده که از یونیکد پشتیبانی میکه.
ببینید اینی که شما میگید به سیستم عامل ارتباطی نداره windowproc کامپوننتها هستند که یونیکد رو تشخیص میدن یعنی اگر داده ها برای کامپوننتهای قبل از 2009 که از یونیکد پشتیبانی نمی کنن با این توصیفی که فرمودید ارسال بشه باید درست کار کنه در صورتی که اینگونه نیست و رست نشون داده نمیشن.
پس هرگز نگید که sendmessage همان کاری رو انجام میده که sendmessagew انجام میده...
اون پایین یک فارسی ساز هست که میتونید برای دو نوع دلفی ازش استفاده کنید و به درست بودن اون مطلبی که ازش یاد کردید یه تجدید نظری بندازید.

vcldeveloper
شنبه 04 تیر 1390, 00:45 صبح
خسته نباشی!
اینطور نیست اونوقت چه لزومی داشت این همه دادو بیداد بشه که کامپایلرهای اومده که از یونیکد پشتیبانی میکه.جان هر کسی که دوست داری، درباره چیزی که ازش اطلاع ندارید اینجا اظهار نظر نکنید! والله دیگه نمیدونم به چه زبونی باید این رو به شما تفهیم کرد!


ببینید اینی که شما میگید به سیستم عامل ارتباطی نداره windowproc کامپوننتها هستند که یونیکد رو تشخیص میدنپسر جان، فقط بخش کوچکی از توابع API ویندوز به پنجره ها مربوط میشه، بخش عمده توابع ویندوز ربطی به پنجره ها و wndproc اونها نداره که به صرف یونیکد بودن یک تابع wndproc، تصور کنی چیزی یونیکد شد؛ ثانیا، یک بار براتون توضیح دادم که یونیکد یک استاندارد نگهداری و ذخیره سازی داده ها ست، پس یک داده یونیکد از زمانی که توسط فرستنده ارسال میشه تا زمانی که به دست گیرنده میرسه باید در ظرف مناسب خودش نگهداری بشه، پس اگر داده ایی بدون رعایت این اصول ارسال بشه، در حین انتقال دچار آسیب میشه و گیرنده پیام حتی اگر امکان تشخیص یونیکد را هم داشته باشه، نمیتونه اون پیام را به درستی دریافت کنه، پس لازمه که فرستنده پیام و منتقل کننده پیام، و گیرنده پیام همگی با یونیکد سازگار باشند، اگر بخشی از این حلقه سازگاری نداشته باشه، پیام خراب میشه.

در سیستم عامل ویندوز پنجره ها به دو دسته پنجره های یونیکد و غیر یونیکد تقسیم میشند، پنجره های یونیکد پیام ها را به صورت یونیکد دریافت می کنند، و پنجره های غیر یونیکد وابسته به CodePage ANSI هستند، برای همین هم در تنظیمات زبان ویندوز یک گزینه برای Non-Unicode Applications وجود داره که در واقع CodePage فعال سیستم برای تبدیل پیام ها به یک پنجره غیر یونیکد را برای ویندوز مشخص میکنه. برای همین هم هست که در هنگام رجیستر کردن یک کلاس پنجره در ویندوز، دو تابع API وجود داره، یکی RegisterClassA و اون یکی RegisterClassW.



اینطور نیست اونوقت چه لزومی داشت این همه دادو بیداد بشه که کامپایلرهای اومده که از یونیکد پشتیبانی میکه.داد بیدادش برای این لازم بود که اولا تا قبل از دلفی 2009، دلفی یک نوع داده پایه برای رشته های یونیکد نداشت. نوع داده string مبتنی بر ANSI بود، نوع داده WideString هم فقط برای سازگاری با COM ارائه شده بود و سربار بسیار بالایی داشت؛ پس اولین کاری که کامپایلر دلفی کرد، ایجاد یک نوع داده پایه جدید با نام UnicodeString بود که کارایی بالای AnsiString رو داشته باشه اما برای داده های یونیکد. همچنین به کامپایلر قابلیت های مختلفی برای تشخیص تبدیل Encoding ها ارائه شده.

جدای از این مورد، سایر اون داد و بیدادهای مد نظر شما به خاطر کامپایلر نبود، بلکه به خاطر کتابخانه بود؛ بین یک کامپایلر و کتابخانه تفاوت وجود داره! اون سر و صداها برای این بود که کل کتابخانه RTL و VCL دلفی که تا قبل از اون با یونیکد سازگار نبودند، با یونیکد سازگار شدند، تا قبل از اون، اگر کسی میخواست برنامه یونیکد با دلفی بنویسه، یا باید از پایه همه چیز را خودش با استفاده از توابع API ویندوز و اشاره گر ها می نوشت، یا باید می رفت سراغ مجموعه هایی مثل TNT Components، که تازه این ها هم نه تنها کامل نبودند، بلکه مبتنی بر استفاده از WideString بودند و کارایی پایینی داشتند. پس ان شاء الله الان متوجه شدید که اون سر و صداها برای چی بود.


پس هرگز نگید که sendmessage همان کاری رو انجام میده که sendmessagew انجام میده...شما اگر خواندن کد بلد هستید، تشریف می برید به یونیت Windows دلفی، و تعریف SendMessage رو اونجا می بینید، بعدش هم تشریف می برید به فایل header مربوطه در Windows SDK، و اونجا هم تعریف تابع فوق رو مشاهده می کنید، بعدش اینجا همچین اظهار نظری می کنید. درباره همین موضوع در سایت MSDN به طور شفاف و روشن توضیح داده شده:

http://msdn.microsoft.com/en-us/library/dd317766%28v=vs.85%29.aspx


خیلی واضح و روشن می بینید که توضیح داده بسیاری از توابع ویندوز دو نسخه Unicode و Ansi دارند و چگونگی تعریف آنها در header های ویندوز را هم شرح داده. البته احتمالا شما از خودِ مایکروسافت بیشتر از سیستم عامل ویندوز خبر دارید! و ایضا در لینک زیر توضیح داده که:

Windows API functions that manipulate characters are generally implemented in one of three formats:


A generic version that can be compiled for either Windows code pages or Unicode
A Windows code page (http://msdn.microsoft.com/en-us/library/dd317752%28v=VS.85%29.aspx) version with the letter "A" used to indicate "ANSI"
A Unicode (http://msdn.microsoft.com/en-us/library/dd374081%28v=VS.85%29.aspx) version with the letter "W" used to indicate "wide"

Some newer functions support only Unicode versions.


http://msdn.microsoft.com/en-us/library/dd374089%28v=VS.85%29.aspx

و همچنین تشریف می برید فصل اول کتاب Windows Internals (http://www.amazon.com/Microsoft-Windows-Internals-4th-Server/dp/0735619174) رو مطالعه می کنید که نوشته:

Unicode
Windows differs from most other operating systems in that most internal text strings are stored and processed as 16-bit-wide Unicode characters. Unicode is an international character set standard that defines unique 16-bit values for most of the world's known character sets. (For more information about Unicode, see http://www.unicode.org as well as the programming documentation in the MSDN Library.)

Because many applications deal with 8-bit (single-byte) ANSI character strings, Windows functions that accept string parameters have two entry points: a Unicode (wide, 16-bit) and an ANSI (narrow, 8-bit) version. The Windows 95, Windows 98, and Windows Millennium Edition implementations of Windows don't implement all the Unicode interfaces to all the Windows functions, so applications designed to run on one of these operating systems as well as Windows typically use the narrow versions. If you call the narrow version of a Windows function, input string parameters are converted to Unicode before being processed by the system and output parameters are converted from Unicode to ANSI before being returned to the application. Thus, if you have an older service or piece of code that you need to run on Windows but this code is written using ANSI character text strings, Windows will convert the ANSI characters into Unicode for its own use. However, Windows never converts the data inside files—it's up to the application to decide whether to store data as Unicode or as ANSI.

In previous editions of Windows, Asian and Middle East editions were a superset of the core U.S. and European editions and contained additional Windows functions to handle more complex text input and layout requirements (such as right-to-left text input). As of Windows 2000, all language editions contain the same Windows functions. Instead of having separate language versions, Windows has a single worldwide binary so that a single installation can support multiple languages (by adding various language packs). Applications can also take advantage of Windows functions that allow single worldwide application binaries that can support multiple languages.


شما درک درستی از یونیکد، چگونگی یونیکد شدن دلفی، و مکانیزم کار ویندوز نداشتید، تابع SendMessage رو به درستی استفاده نکردید، و جواب هم نگرفتید. براتون توضیح داده شد، ظاهرا مشکل تون هم حل شد، اما همچنان به آسمان و ریسمان بافی مشغولید!

پس خواهش می کنم، لطف کن، و همینطوری روی هوا اظهار نظر نکن، با این کار فقط وقت خودت و من و دیگران رو هدر میدی.

با تشکر

tdkhakpur
شنبه 04 تیر 1390, 01:02 صبح
پس خواهش می کنم، لطف کن، و همینطوری روی هوا اظهار نظر نکن، با این کار فقط وقت خودت و من و دیگران رو هدر میدی.


مگه ما غیر از این گفته بودیم؟این مطالب رو برای کی توضییح میدید؟!!!
فارسی ساز مستقل از ویندوز برای کامپایلرهای 2009 و به (http://barnamenevis.org/showthread.php?292662-فارسی-ساز-مستقل-از-ویندوز-برای-کامپایلرهای-2009-و-به-بعد)

vcldeveloper
شنبه 04 تیر 1390, 06:46 صبح
مگه ما غیر از این گفته بودیم؟این مطالب رو برای کی توضییح میدید؟!!!
بله که غیر از این گفته بودید، عجب بساطی شده ها! این همه نقل قولی که از شما در همین تاپیک درج کردم و در جوابش توضیح دادم، از مریخ اومدند؟!!

یکی دیگه اومده بود اینجا با ID شما پست ارسال میکرد که یونیکد بودن ربطی به سیستم عامل نداره؟ یا اینکه PChar = PWideChar نیست؟ یا اینکه SendMessage = SendMessageW نیست؟ یا کس دیگه ایی اومده بود اینجا مدعی شده بود که اشتباه کردند SendMessage رو معادل SendMessageW گرفتند؟! حکایتی شده!



فارسی ساز مستقل از ویندوز برای کامپایلرهای 2009 و به (http://barnamenevis.org/showthread.php?292662-%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-%D8%B3%D8%A7%D8%B2-%D9%85%D8%B3%D8%AA%D9%82%D9%84-%D8%A7%D8%B2-%D9%88%DB%8C%D9%86%D8%AF%D9%88%D8%B2-%D8%A8%D8%B1%D8%A7%DB%8C-%DA%A9%D8%A7%D9%85%D9%BE%D8%A7%DB%8C%D9%84%D8%B1%D 9%87%D8%A7%DB%8C-2009-%D9%88-%D8%A8%D9%87-%D8%A8%D8%B9%D8%AF)

آخه من میگم شما درک درستی از یونیکد و دلفی و ویندوز ندارید، انکار می کنید! عزیز جان، دلفی 2009 و نسخه های بعد از آن پشتیبانی شون از یونیکد و به تبع آن زبان فارسی به واسطه ویندوز هست؛ یعنی چون ویندوز یونیکد هست و این قابلیت ها رو از نسخه ویندوز 2000 به بعد فراهم کرده، دلفی پشتیبانی از یونیکد رو به شما میده؛ و در دل این پشتیبانی همچنان توابع API ویندوز خوابیده. حالا مضحک نیست که یکی بیاد بگه فارسی ساز مستقل از ویندوز برای کامپایلر دلفی 2009؟!!! دلفی 2009 خودش سر تا پا وابسته به ویندوزه، شما رفتید از مریخ تابع آوردید؟ همین توابع ویندوز هست که دلفی براشون Wrapper نوشته، و شما هم برای اون Wrapper ها Wrapper نوشتید. پشتیبانی از یونیکد بدون پشتیبانی سیستم عامل از آن معنی نداره، مگر اینکه یکی بخواد تمامی کارهای نگهداری از ساختارهای داده برنامه خودش، و رسم متون را با تمام جزئیاتش خودش پیاده سازی کنه، تازه حتی در اون صورت هم برنامه اش امکان به اشتراک گزاری داده هایش با سایر برنامه ها را نخواهد داشت. پس چیزی که شما نوشتید، فارسی ساز مستقل از ویندوز نیست! امیدوارم یک ساعت دیگه مدعی نشید که اصلا این عبارت هم از شما نبوده، یکی دیگه اینو گفته.

tdkhakpur
شنبه 04 تیر 1390, 13:40 عصر
عجب بساطی شده ها! این همه نقل قولی که از شما در همین تاپیک درج کردم و در جوابش توضیح دادم، از مریخ اومدند؟!!

شما هم دیگه یواش یواش دارید شور احترام در در میارید.


حالا مضحک نیست که یکی بیاد بگه فارسی ساز مستقل از ویندوز برای کامپایلر دلفی 2009؟!!!

اوضاع احوال نشون میده یه ذره اعصابت خورده و معلوم میشه دانسته هایت در حد حرف و ارسال طومار هست.


همین توابع ویندوز هست که دلفی براشون Wrapper نوشته، و شما هم برای اون Wrapper ها Wrapper نوشتید. پشتیبانی از یونیکد بدون پشتیبانی سیستم عامل از آن معنی نداره، مگر اینکه یکی بخواد تمامی کارهای نگهداری از ساختارهای داده برنامه خودش، و رسم متون را با تمام جزئیاتش خودش پیاده سازی کنه، تازه حتی در اون صورت هم برنامه اش امکان به اشتراک گزاری داده هایش با سایر برنامه ها را نخواهد داشت

این حرفها چه ربطی به موضوع داره فارسی سازی چه ربطی به ترسیم داره فقط کافی درایور برای کیبورد نوشته بشه که اون هم نوشته شده و بالا لینکش قرارداده شده.


دلفی 2009 خودش سر تا پا وابسته به ویندوزه، شما رفتید از مریخ تابع آوردید؟

یعنی چی مریخ خوب فارسی سازه همینه و مشکلی هم نداره خب اگر به درت نمی خوره استفاده نکن در هر صورت یه ذره برو بازار کار نرم افزار خواهید دید فارسی ساز مستقل از ویندوز چیه و کجا کاربرد داره و کجا میشه ازش استفاده کرد.


چیزی که شما نوشتید، فارسی ساز مستقل از ویندوز نیست! امیدوارم یک ساعت دیگه مدعی نشید که اصلا این عبارت هم از شما نبوده، یکی دیگه اینو گفته.
خنده داره!شما یه ویندوز نصب کن و فارسی رو درش حذف کن ببین این فارسی ساز میتونه برات فارسی سازی کنه یا نه!
خلاصه زیاد مطلب ارسال میکنی و همیشه هم شاکی هست اگه بدونیم مشکلت چیه خیلی خوب میشه.

vcldeveloper
یک شنبه 05 تیر 1390, 03:30 صبح
این حرفها چه ربطی به موضوع داره فارسی سازی چه ربطی به ترسیم داره فقط کافی درایور برای کیبورد نوشته بشه که اون هم نوشته شده و بالا لینکش قرارداده شده.
پسر جان، وقتی میگم نمیدونی یونیکد چی هست، برای من از این پست های جالب انگیزناک ارسال میکنی! درایور کیبورد نصب کنی، میشه یونیکد؟! که اومدی در تاپیک مربوط به ارسال رشته یونیکد لینکش رو قرار دادی و اسم توابعت هم گذاشتی InstallUnicodeAction و RemoveUnicodeAction؟!! تازه حتی برای مپ کردن همون کارکترهای درایور کیبوردت هم باید به توابع یونیکد ویندوز اتکا کنی، در حالی که چند پست قبل مدعی بودی که این اصلا به سیستم عامل ربطی نداره!


شما یه ویندوز نصب کن و فارسی رو درش حذف کن ببین این فارسی ساز میتونه برات فارسی سازی کنه یا نه!
اون چیزی که تو بهش میگی فارسی در ویندوز، مربوط به پشتیبانی از یونیکد در ویندوز نیست، بلکه اون "فارسی" که به قول تو در ویندوز حذف یا نصب میشه، در واقع یک فایل کیبورد هست، به همراه تنظیماتی برای نمایش صحیح عبارت راست-به-چب در ویندوز؛ نه پشتیبانی یا عدم پشتیبانی از یونیکد. در واقع چه اون تنظیمات ویندوز بر روی فارسی تنظیم باشه، چه نباشه، ویندوز میتونه به درستی با داده های یونیکد (من جمله داده های یونیکد به زبان فارسی) کار کنه، و آنها را ذخیره کرده یا انتقال بده، اما برای نمایش آنها در بعضی کنترل ها و همچنین چینش درست کارکترها در هنگام تایپ کاربر، از اون تنظیمات استفاده میکنه؛ پس این اون ادعای جنابعالی هست خنده داره!

عنوانی که باید برای DLL ات انتخاب میکردی، باید میشد، تایپ فارسی در ویندوز بدون نیاز به نصب کیبورد فارسی؛ و ارتباطی هم با عنوان و موضوع این تاپیک پیدا نمی کرد.


شما هم دیگه یواش یواش دارید شور احترام در در میارید.
والله این احترامی که تو اینجوری رعایتش میکنی، برای من از صدتا فحش بدتره، که یکی بیاد اینطوری بدون اطلاع از یک موضوع فنی، درباره اون موضوع اظهار نظر کنه، و هر چی هم براش آیه و حدیث میارن، همه رو بدون دلیل رد کنه!


خلاصه زیاد مطلب ارسال میکنی و همیشه هم شاکی هست اگه بدونیم مشکلت چیه خیلی خوب میشه.
خوب شد گفتی؛ مشکل من با تو و امثال تو هست که هر از چند گاهی یک مطلب غیر فنی با نام مطلب فنی و "حرفه" ایی اینجا ارسال می کنید، و هر چی هم که براتون دلایل فنی آورده میشه که آقا این برداشتت به این N دلیل، غلطه، زیر بار نمیرید، بعد از مدتی هم که خودتون متوجه اشتباه تون میشید، به جای پذیرش اشتباه، کلا منکر همه چی میشید! مثل جنابعالی که عدم دقت خودت در فراخوانی صحیح تابع SendMessage ویندوز در دلفی 2009 رو گذاشتی به حساب مشکل دلفی و ویندوز، وقتی هم که بعد از کلی صرف وقت و زحمت متوجه ات کردیم که این SendMessage همون SendMessageW هست، و برات توضیح دادیم که ویژگی Script یک فونت ربطی به یونیکد بودن متن نداره، و سایر قضایا که شرحش در همین تاپیک موجوده، و اون نمونه کدی که گذاشتی و بهت گفتم اشتباه داری SendMessage رو فراخوانی میکنی، و شکل صحیح اش این نیست؛ تازه مدعی شدی که خودت هم از اول همین رو میگفتی!

البته که اینجور رفتارها من رو عصبانی میکنه، چون به خاطر اظهار نظر غیر فنی و غیر مسئولانه جنابعالی، برای اینکه سایر کاربران با طناب تو به ته چاه نیافتند، من یا هر کاربر دلسوز دیگه اینجا باید کلی مطلب بنویسه و دلیل و مدرک بیاره که اظهارات این آقا در این موضوع خاص فاقد پایه و اساس علمی و فنی هست. در حالی که اگر همون ابتدا به توصیه ایی که بهت شده بود توجه می کردی، یا حداقل با اون همه دلیل و توضیح قبول می کردی که واقعا اشتباه کردی، و ادعاهای مضحک نمیکردی، هم خودت زودتر به نتیجه می رسیدی و هم وقت من رو تلف نمی کردی. بارها در تاپیک های مختلف همچین رفتاری داشتی و بارها هم برات توضیح داده شد، ولی چه کنم که نرود میخ آهنین در سنگ!

tdkhakpur
یک شنبه 05 تیر 1390, 21:28 عصر
در واقع چه اون تنظیمات ویندوز بر روی فارسی تنظیم باشه، چه نباشه، ویندوز میتونه به درستی با داده های یونیکد (من جمله داده های یونیکد به زبان فارسی) کار کنه، و آنها را ذخیره کرده یا انتقال بده، اما برای نمایش آنها در بعضی کنترل ها و همچنین چینش درست کارکترها در هنگام تایپ کاربر، از اون تنظیمات استفاده میکنه؛ پس این اون ادعای جنابعالی هست خنده داره!

تو هم ما رو گرفتی ها!!
خب عزیز چرا خودت رو خسته میکنی یک ویندوز خالی نصب کن فارسی درش نباشه میتونی فارسی تایپ کنی؟


هر چی هم که براتون دلایل فنی آورده میشه که آقا این برداشتت به این N دلیل، غلطه، زیر بار نمیرید، بعد از مدتی هم که خودتون متوجه اشتباه تون میشید، به جای پذیرش اشتباه، کلا منکر همه چی میشید!

کدوم دلایل - راهی رو که نرفتی رو دلیل قرار میدی؟
اگه طرف قضیه رو برعکس نگاه کنید این شمایید که به اشتباه خودتان پی برده و پاسخهایتان طی مراحلی که ارسال میکنید تغییر و جهت مثبت پیدا میکنه به قول تهرونیا مسئله رو به نفع خودت می پیچونی.
ببینید از اون اول به پاسخهای که ارسال کردید نگاه کنید رفتید از منابع جستجو کردید و برای ما مطلب ارسال میکنید خوب دست ما که کج نیست ما هم میتونستم این کار رو انجام بدیم به همین دلیل اینجا سوال رو مطرح کردم تا زودتر به نتیجه برسم نه اینکه باعث بشه به همدیگه شاخ بکشیم.

هم خودت زودتر به نتیجه می رسیدی و هم وقت من رو تلف نمی کردی.
ببین جناب کشاورز کسی مجبورت نکرده وقتت رو برای پاسخ تلف بکنی و ثانیا اینکه هیچ وقت کارهای تئوری نمیتونه همان قدرتی را داشته باشه که کار عملی داره به همین خاطر وقتی کس ازتون ایراد میگیره فکر نکنید فلان جا نوشته شده درست هست.

ahmad_eagle2002
دوشنبه 03 مرداد 1390, 02:08 صبح
جناب tdkhakpur فکر میکنم اگر مطالب آقای کشاورز رو با دقت وبی غرض مطالعه بفرمایید نتیجه بهتری انشالله میگیرید
قصد جسارت به شما رو ندارم ولی این جمله
ببین جناب کشاورز کسی مجبورت نکرده وقتت رو برای پاسخ تلف بکنی
خیلی ناراحتم کرد .چون وقتی اساتیدی مثل آقای کشاورز وقتشون در اختیار همه اینجوری قرار میدن انتظار تشکر از ایشون میره نه جمله بالای شما