سئوال درباره ی API های ویندوز

شروع موضوع توسط SajjadKhati ‏12 نوامبر 2017 در انجمن منطق و الگوریتم برنامه‌نویسی

  1. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63
    سلام
    استاد علی ، در قضیه ی استفاده از تابع api برای فونت ، در استراکچر CHOOSEFONT ، فیلدی بنام lpTemplateName و lpszStyle دارن که به ترتیب از نوع های LPCTSTR و LPTSTR هستن که کلا رشته هستن ولی برخلاف فیلد lfFaceName در استراکچر CHOOSEFONT که از نوع TCHAR و کلا رشته هست و در فیلد lfFaceName ، گفت که 32 بایت لازم داره ؛ ولی در فیلدهای lpTemplateName و lpszStyle نگفت . در اینجا باید چند بایت براشون فضا بگیریم؟ و از کجا باید متوجه بشیم چند بایت بگیریم؟ آخه گفتین که 1 بایت کم و زیاد شدن برای استراکچر ، خطا میده
    دوم اینکه هر جا نوع کاراکتر ، ansi بخواد (8 بیت) ولی ما نوع کاراکتر رو ascii بدیم (7 بیت) ، برای نام فونت (و هر چیزی که اسم میخواد) ، اشکال داره؟
     
    نوشته شده توسط SajjadKhati در ‏12 نوامبر 2017
  2. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63
    من که قاتی کردم
    کد زیر رو نوشتم ولی تا حالا که دیالوگ فونت بالا میومد ، همین قدر هم دیگه بالا نمیاد! :


    کد (Text):
     _LogFont = Memory.CreateStructure("long, long, long, long, long, byte, byte, byte, byte, byte, byte, byte, byte, char[32]");  -- ÇÓÊÑǘÑ ãÑÈæØ Èå ÇØáÇÚÇÊ LOGFONT
    Memory.SetStructureData(_LogFont, 1, 0, 0, ""); -- lfHeight
    Memory.SetStructureData(_LogFont, 2, 0, 0, ""); -- lfWidth
    Memory.SetStructureData(_LogFont, 3, 0, 0, ""); -- lfEscapement
    Memory.SetStructureData(_LogFont, 4, 0, 0, ""); -- lfOrientation
    Memory.SetStructureData(_LogFont, 5, 0, 400, ""); -- lfWeight
    Memory.SetStructureData(_LogFont, 6, 0, 1, ""); --Italic
    Memory.SetStructureData(_LogFont, 7, 0, 1, "");  --Underline
    Memory.SetStructureData(_LogFont, 8, 0, 1, "");  --StrikeOut
    Memory.SetStructureData(_LogFont, 9, 0, 0, "");  --Ansi_CHARSET
    Memory.SetStructureData(_LogFont, 10, 0, "OUT_TT_PRECIS", "");  --OutPrecision
    Memory.SetStructureData(_LogFont, 11, 0, "CLIP_DEFAULT_PRECIS", "");   --ClipPrecision
    Memory.SetStructureData(_LogFont, 12, 0, 4, "");    --FontQuality
    Memory.SetStructureData(_LogFont, 13, 0, 1, "");    --PitchAndFamily  FIXED_PITCH
      Memory.SetStructureData(_LogFont, 14, 1, 73, "");    --FaceName  chaharomin arguman , code ascii hast . reshteh "Impact"
      Memory.SetStructureData(_LogFont, 14, 2, 109, "");    --FaceName
      Memory.SetStructureData(_LogFont, 14, 3, 112, "");    --FaceName
      Memory.SetStructureData(_LogFont, 14, 4, 97, "");    --FaceName
      Memory.SetStructureData(_LogFont, 14, 5, 99, "");    --FaceName
      Memory.SetStructureData(_LogFont, 14, 6, 116, "");    --FaceName

    chooseFont = Memory.CreateStructure("long, long, long, long, long, long, long, long, long, long, long, long, short, long, long");  -- ÇÓÊÑǘÑí ˜å ãÑÈæØ Èå ÇØáÇÚÇÊÇÓÊÑǘÑ CHOOSEFONT åÓÊ
    Memory.SetStructureData(chooseFont, 1, 0, Memory.Size(chooseFont), "");  -- lStructSize
    Memory.SetStructureData(chooseFont, 2, 0, Application.GetWndHandle(), "");  -- hwndOwner
    Memory.SetStructureData(chooseFont, 4, 0, _LogFont, "");  -- lpLogFont
    Memory.SetStructureData(chooseFont, 5, 0, 0x00000100, "");  -- iPointSize
    Memory.SetStructureData(chooseFont, 6, 0, 0x02030041, "");   --Flags  CF_SCREENFONTS | CF_FORCEFONTEXIST | CF_INACTIVEFONTS | CF_INITTOLOGFONTSTRUCT | CF_SCALABLEONLY
    Memory.SetStructureData(chooseFont, 7, 0, "255", "");  -- rgbColors
    Memory.SetStructureData(chooseFont, 8, 0, "", "");  -- lCustData
    Memory.SetStructureData(chooseFont, 9, 0, "", "");  -- lpfnHook
    Memory.SetStructureData(chooseFont, 10, 0, "", "");  -- lpTemplateName string
    Memory.SetStructureData(chooseFont, 11, 0, "", "");  -- hInstance
    Memory.SetStructureData(chooseFont, 12, 0, "", "");  -- lpszStyle string
    Memory.SetStructureData(chooseFont, 13, 0, 0x0100, "");  --nFontType  BOLD_FONTTYPE
    Memory.SetStructureData(chooseFont, 14, 0, 64, "");  -- nSizeMin
    Memory.SetStructureData(chooseFont, 15, 0, 64, "");  -- nSizeMax
    local isOkSelect = DLL.CallFunction("comdlg32.dll", "ChooseFontA", chooseFont, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL);  -- ÝÑÇÎæäí ÊÇÈÚ ChooseFont ˜å ÏÑ ÝÇíá Comdlg32.dll åÓÊ

    if (tonumber(isOkSelect) == 1) then  -- ÇÑ ˜ÇÑÈÑ ok ÑÇ ÇäÊÎÇÈ ˜ÑÏ
        --result = Subclass.Create(Application.GetWndHandle());


         fPtr = Memory.GetStructureData(_LogFont, 14, 0, "");  -- ÇØáÇÚÇÊ ÐÎíÑå ÔÏå ÏÑ åÇÑÏåãíä ÇÓÊÑǘÑ ÇÓÊÑǘÑ _LogFont Ñæ ȐíÑ
        Dialog.Message("Notice", fPtr, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);
    end
     

    نمیدونم چرا با کد زیر بالا میاد ولی با کد بالا نه ! :


    کد (Text):
    local _LogFont = Memory.CreateStructure("long, long, long, long, long, long, long, long, long, long, long, long, long, long");
    Memory.SetStructureData(_LogFont, 1, 0, "<0", "");
    Memory.SetStructureData(_LogFont, 2, 0, "0", "");
    Memory.SetStructureData(_LogFont, 3, 0, "20", "");
    Memory.SetStructureData(_LogFont, 4, 0, "20", "");
    Memory.SetStructureData(_LogFont, 5, 0, "400", "");
    Memory.SetStructureData(_LogFont, 6, 0, true, ""); --Italic
    Memory.SetStructureData(_LogFont, 7, 0, true, "");  --Underline
    Memory.SetStructureData(_LogFont, 8, 0, true, "");  --StrikeOut
    Memory.SetStructureData(_LogFont, 9, 0, "0xB2", "");  --ARABIC_CHARSET
    Memory.SetStructureData(_LogFont, 10, 0, "OUT_TT_PRECIS", "");  --OutPrecision
    Memory.SetStructureData(_LogFont, 11, 0, "CLIP_DEFAULT_PRECIS", "");   --ClipPrecision
    Memory.SetStructureData(_LogFont, 12, 0, "0x04", "");    --FontQuality
    Memory.SetStructureData(_LogFont, 13, 0, "1", "");    --PitchAndFamily  FIXED_PITCH

    Memory.SetStructureData(_LogFont, 14, 0, "Arial", "");    --FaceName

    local str = Memory.CreateStructure("long, long, long, long, long, long, long, long, long, long, long, long, long, long, long");

    Memory.SetStructureData(str, 1, 0, Memory.Size(str), "");
    Memory.SetStructureData(str, 2, 0, Application.GetWndHandle(), "");
    Memory.SetStructureData(str, 4, 0, _LogFont, "");
    Memory.SetStructureData(str, 5, 0, "0x00000100", "");
    Memory.SetStructureData(str, 6, 0, "0x00000100", "");   --Flags
    Memory.SetStructureData(str, 7, 0, "255", "");
    Memory.SetStructureData(str, 8, 0, "", "");
    Memory.SetStructureData(str, 9, 0, "", "");
    Memory.SetStructureData(str, 10, 0, "", "");
    Memory.SetStructureData(str, 11, 0, "", "");
    Memory.SetStructureData(str, 12, 0, "", "");
    Memory.SetStructureData(str, 13, 0, "0x0100", "");  --BOLD_FONTTYPE
    Memory.SetStructureData(str, 14, 0, 6, "");
    local result = DLL.CallFunction("comdlg32.dll", "ChooseFontA", str, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL);

    if result~=false then
         _c = Memory.GetStructureData(str, 5, 0, "");  --  _GetFontSize

         Dialog.Message("", _c);
    end
    Memory.FreeStructure(_LogFont);
    Memory.FreeStructure(str);
     
    نوشته شده توسط SajjadKhati در ‏13 نوامبر 2017
  3. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63
    سلام مجدد
    کدش رو فهمیدم یعنی مقدار بازگشتی نام رشته رو درست برمیگردونه


    کد (Text):
    local _LogFont = Memory.CreateStructure("long, long, long, long, long, byte, byte, byte, byte, byte, byte, byte, byte, char[32]");
    Memory.SetStructureData(_LogFont, 1, 0, "<0", "");
    Memory.SetStructureData(_LogFont, 2, 0, "0", "");
    Memory.SetStructureData(_LogFont, 3, 0, "20", "");
    Memory.SetStructureData(_LogFont, 4, 0, "20", "");
    Memory.SetStructureData(_LogFont, 5, 0, "400", "");
    Memory.SetStructureData(_LogFont, 6, 0, true, ""); --Italic
    Memory.SetStructureData(_LogFont, 7, 0, true, "");  --Underline
    Memory.SetStructureData(_LogFont, 8, 0, true, "");  --StrikeOut
    Memory.SetStructureData(_LogFont, 9, 0, "0xB2", "");  --ARABIC_CHARSET
    Memory.SetStructureData(_LogFont, 10, 0, "OUT_TT_PRECIS", "");  --OutPrecision
    Memory.SetStructureData(_LogFont, 11, 0, "CLIP_DEFAULT_PRECIS", "");   --ClipPrecision
    Memory.SetStructureData(_LogFont, 12, 0, "0x04", "");    --FontQuality
    Memory.SetStructureData(_LogFont, 13, 0, "1", "");    --PitchAndFamily  FIXED_PITCH

         Memory.SetStructureData(_LogFont, 14, 1, 73, "");    --FaceName "Impact"
          Memory.SetStructureData(_LogFont, 14, 2, 109, "");    --FaceName "Impact"
          Memory.SetStructureData(_LogFont, 14, 3, 112, "");    --FaceName "Impact"
          Memory.SetStructureData(_LogFont, 14, 4, 97, "");    --FaceName "Impact"
          Memory.SetStructureData(_LogFont, 14, 5, 99, "");    --FaceName "Impact"
          Memory.SetStructureData(_LogFont, 14, 6, 116, "");    --FaceName "Impact"


    local str = Memory.CreateStructure("long, long, long, long, long, long, long, long, long, long, long, long, long, long, long");
    Memory.SetStructureData(str, 1, 0, Memory.Size(str), "");
    Memory.SetStructureData(str, 2, 0, Application.GetWndHandle(), "");
    Memory.SetStructureData(str, 4, 0, _LogFont, "");
    Memory.SetStructureData(str, 5, 0, "0x00000100", "");
    Memory.SetStructureData(str, 6, 0, "0x00000100", "");   --Flags
    Memory.SetStructureData(str, 7, 0, "255", "");
    Memory.SetStructureData(str, 8, 0, "", "");
    Memory.SetStructureData(str, 9, 0, "", "");
    Memory.SetStructureData(str, 10, 0, "", "");
    Memory.SetStructureData(str, 11, 0, "", "");
    Memory.SetStructureData(str, 12, 0, "", "");
    Memory.SetStructureData(str, 13, 0, "0x0100", "");  --BOLD_FONTTYPE
    Memory.SetStructureData(str, 14, 0, 6, "");
    local isOkSelect = DLL.CallFunction("comdlg32.dll", "ChooseFontA", str, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL);  -- فراخوني تابع ChooseFont که در فايل Comdlg32.dll هست

    if (tonumber(isOkSelect) == 1) then
        myString = Memory.GetString(_LogFont + 28, -1, "Ascii");
     
         fPtr = Memory.GetStructureData(_LogFont, 14, 1, "");  -- اطلاعات ذخيره شده در چهاردهمين استراکچر استراکچر _LogFont رو بگير
        Dialog.Message("Notice", myString, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);
    end
     

    ولی کد اسکی رشته ی "Impact" رو بصورت پیش فرض که بهش میدم ، اولا با کد بالا ، فقط 3 حرف آخرش رو برمیگردونه یعنی "act" رو برمیگردونه و در صفحه ی دیالوگ فونت ، بصورت پیش فرض فونتی با نام "Impact رو انتخاب نمیکنه . دوما که کاراکترها رو که به اندازه ی 4 کاراکتر جلوتر مینویسم یعنی قسمتی از کد بالا رو به شکل زیر تغییر میدم :


    کد (Text):
         Memory.SetStructureData(_LogFont, 14, 4, 73, "");    --FaceName "Impact"
          Memory.SetStructureData(_LogFont, 14, 5, 109, "");    --FaceName "Impact"
          Memory.SetStructureData(_LogFont, 14, 6, 112, "");    --FaceName "Impact"
          Memory.SetStructureData(_LogFont, 14, 7, 97, "");    --FaceName "Impact"
          Memory.SetStructureData(_LogFont, 14, 8, 99, "");    --FaceName "Impact"
          Memory.SetStructureData(_LogFont, 14, 9, 116, "");    --FaceName "Impact"
         myString = Memory.GetString(_LogFont + 28, -1, "Ascii");
        Dialog.Message("Notice", myString, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);
     

    این بار ، استعلامش درسته یعنی در کد ، رشته ی "Impact" رو چاپ میکنه ولی باز هم در صفحه ی دیالوگ فونت ، بصورت پیش فرض فونتی با نام "Impact رو انتخاب نمیکنه .
    چرا؟!! نمیدونم
     
    نوشته شده توسط SajjadKhati در ‏13 نوامبر 2017
  4. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,340
    تشکر شده:
    10,283
    امتیاز دستاورد:
    113
    شما ساختار CHOOSEFONT رو که تجربی کشف نمی کنین، به مستنداتش تو MSDN رجوع می کنین. یکبار این دو تا ساختار رو در MSDN ببینید بعد بینید جای ابهام داره یا نه. که وقتی اینکار رو بکنین می بینین تعریف lpTemplateName و lpszStyle شباهتی به lfFaceName نداره که بهم ربطش می دید. نوع داده شون شبیه هم نیست که طول براش مشخص کنه، تو MSDN ببینید دو تا structure رو، اون یه آرایه با طول ثابت بود، lpTemplateName و lpszStyle اشاره گر به رشته است، اشاره گر به رشته مگه طول رشته لازم داره که بگه چند کاراکتر باشه یا روی طول حافظه struct تاثیر بذاره؟ طول اشاره گر مشخص و ثابته، یا 32 بیتی ئه، یا 64 بیتی. برنامه تون در مود x86 اجرا بشه 4 بایته، در مود x64 اجرا بشه 8 بایته که اینم به این بستگی داره که برنامه تون 32 بیتی باشه یا 64 بیتی.
    lpTemplateName هم کلا مقداریه که ورودیه، شما تعیین اش می کنید، طول رشته اش رو هم به رشته ای که میدید بستگی داره، خروجی نداره که بگیم طول بافر چقدر باشه که جا بشه.
    برای طول lpszStyle هم مایکروسافت نمی تونه طول متعارف یا حداقل یا حداکثر مشخصه کنه، در هر موردی که میشده همچین چیزی تعیین بشه توصیه کرده که بافر حداقل برای فلان تعداد کاراکتر جا داشته باشه. این دیگه بستگی به طراح فونت داره، هر فونتی و با هر زبانی ممکنه طول Style متفاوتی داشته باشه. استفاده ازش رو هم توصیه نکرده چون مقادیر استاندارد نیست، طراح فونت میتونه هر اسم style ای رو برای فونت اش ثبت کنه. بالاخره اون ساختار CHOOSEFONT با Windows 95 ئه 1995 هم استفاده میشده، نمیتونیم بگیم این همه سال ازش برنامه نویس ها استفاده می کنند ولی مستنداتش ناقصه و کامل توضیح داده نشده.

    بله، برای اسامی که کاراکتر خارج از محدوده Character Set دارند ایراد داره، اما کلا در سیستم عاملی که Unicode ئه و با رشته های Unicode سر و کار داره خود ANSI ئه 8 بیتی با هر Character Set ای که باشه مشکل سازه.
    با مسیر فایل و فولدر مشکل دارند، با اسامی فونت مشکل دارند، با اسامی فیلد های پایگاه داده و مرتب سازی رشته ها و کاراکتر های کنترلی متن و پاراگراف بندی و ...
     
    نوشته شده توسط the_king در ‏13 نوامبر 2017
    SajjadKhati از این پست تشکر کرده است.
  5. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63

    آها
    ممنون استاد علی
    پس هر جا نوعش نوشته LPCTSTR و LPTSTR که مخفف Long Point T String (حالا کلا دقیقا همه ی کلماتش رو نمیدونم:green:) ، چون گفته Point پس منظورش اینه که اشاره گر به رشته میخواد و چون اشاره گره ، طول رشته رو هر چقدر که دلمون خواست میتونیم بذاریم . درسته؟
    و معمولا هر جای دیگه ای که نوع TCHAR بخواد ، اولا چون نوع Char رو خواست و نگفت که اشاره گر میخواد ، پس نباید اشاره گر بهش بدیم بلکه باید آرایه ای از کاراکترها بهش بدیم . درسته؟

    درباره ی ansi و unicode هم اگه کد اسکی حروف ، از 127 بیشتر نشه که مشکلی پیش نمیاد دیگه؟
     
    نوشته شده توسط SajjadKhati در ‏13 نوامبر 2017
  6. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,340
    تشکر شده:
    10,283
    امتیاز دستاورد:
    113

    طول رشته رو ممکنه هر چقدر دلتون بخواد نتونید بذارید ولی به هر حال اولا طولش متغیر ئه و ثانیا فقط اشاره گر اش جزئی از ساختار ئه.
    آرایه با طول ثابت مقدار مشخصی برای طول داره، دیگه از این مشخص تر نمیتونه تعریفی باشه که بگید چطوری تفاوت اش رو تشخیص بدیم. TCHAR نباشه، بایت باشه، WORD باشه، WCHAR باشه، اون قسمتش مهم نیست، مهم اینه که بعد اسم متغیر [size] ای در کار باشه که size مشخص کننده طول آرایه است.
    طبق تعاریف سیستم عامل معمولا تعاریفی که با LP و P شروع بشه یعنی اشاره گر ئه، C داشته باشه یعنی ANSI ئه، W داشته باشه یعنی Unicode ئه و T داشته باشه یعنی ANSI/Unicode بودنش مشخص نیست و بنا به شرایط زمان کامپایل همه اون T ها در کد یا ANSI می شوند یا همه اونها Unicode می شوند.
    TCHAR یعنی کاراکتری که ممکنه ANSI باشه یا Unicode باشه. یعنی برنامه نویس موقع کد نویسی تصمیم نمیگیره که کد اش برای محیط ANSI ئه یا Unicode. کامپایلر موقع کامپایل بر اساس شرایط محیط و سیستم عامل تصمیم می گیره یا تنظیم میشه که TCHAR ها یک بایتی باشند یا دو بایتی.
    نه، مشکلی پیش نمیاد.
     
    نوشته شده توسط the_king در ‏14 نوامبر 2017
    SajjadKhati از این پست تشکر کرده است.

به اشتراک بگذارید