c# - ডিপিআই সচেতনতা-একটি প্রকাশে অজানা, অন্যটিতে সিস্টেম সচেতন



.net winforms (1)

সুতরাং আমরা এই সত্যিই বিজোড় সমস্যা আছে। আমাদের অ্যাপ্লিকেশনটি একটি সি # / উইনফর্মস অ্যাপ্লিকেশন। আমাদের 6.0 রিলিজে, আমাদের অ্যাপ্লিকেশনটি ডিপিআই সচেতন নয়। আমাদের 6.1 প্রকাশে এটি হঠাৎ করে ডিপিআই সচেতন হয়ে উঠেছে।
.0.০ রিলিজে, আপনি যদি এটি উচ্চ ডিপিআইতে চালিত করেন তবে এটি উইন্ডোজ বিটম্যাপ স্কেলিং ব্যবহার করে, যা ভাল, কারণ এটি স্ক্রিন লেআউটকে প্রভাবিত করে না। .1.১ রিলিজে, কারণ এটি কোনও কারণে ডিপিআই সচেতন হয়েছে, ব্যবহারকারী ইন্টারফেসগুলি ম্যাঙ্গাল হয়ে যায়।
আমরা এখনই এটি ঠিক করার মতো অবস্থানে নেই। আমাদের কয়েকশ স্ক্রিন রয়েছে, সুতরাং এগুলি সমস্ত ডিপিআই সচেতন মোডে সঠিকভাবে কাজ করাতে অনেক সময় লাগবে।

সিসইন্টার্নালস প্রসেস এক্সপ্লোরার ব্যবহার করে আমরা এটি নিশ্চিত করেছি। আমাদের .0.০ রিলিজে এটি অজানা দেখায়, তবে আমাদের .1.১ রিলিজে এটি প্রাথমিকভাবে অজানা দেখায় তবে তারপরে সিস্টেম সচেতনতায় পরিবর্তিত হয়।
পরবর্তীটি ঘটে যখন কোডটি এসইএসই থেকে আমাদের সমাবেশ ডিএলএল এর ভিতরে প্রবেশ করে যাতে আমাদের সমস্ত ইউজার ইন্টারফেস কোড থাকে (আমাদের EXE মূলত একটি খুব পাতলা শেল; এটি আসলে যা করে তা আমাদের উপস্থাপনা স্তর সমাবেশে একটি নিয়ামক শ্রেণি কল করে call)

আমরা নিম্নলিখিতটি নিশ্চিত করেছি:

  • দুটি সংস্করণ ভিএসএস 2017 ব্যবহার করে রিলিজ মোডে নির্মিত।
  • উভয় সংস্করণ একই লক্ষ্য। নেট ফ্রেমওয়ার্ক (4.5)
  • উভয় সংস্করণ একই ডিভ এক্সপ্রেস সংস্করণ ব্যবহার করে।
  • উভয় সংস্করণে একই অ্যাপ্লিকেশন ম্যানিফেস্ট রয়েছে, এতে ডিপিআই সচেতনতা সেটিংস সক্ষম নেই।
  • কোনও ডিপিআই সম্পর্কিত উইন্ডোজ এপিআই-তে কোনও সংস্করণের কোনও কল নেই।
  • সিস ইন্টারনাল এবং কিছু বার্তা বাক্স ব্যবহার করে আমরা নির্ধারণ করেছিলাম যে release.১ রিলিজটি কোন পর্যায়ে সচেতন হয় (উপস্থাপনা সমাবেশে প্রবেশের পয়েন্ট) এবং ডিএলএলগুলি কীভাবে লোড হয় (আমাদের, ডিভ এক্সপ্রেস, অন্যান্য নির্ভরতা) এবং তারপরে আমরা একটি ছোট ডামি অ্যাপ তৈরি করেছি যা একই ডিএলএলগুলি উল্লেখ করে এবং নিশ্চিত করে যে এগুলি লোড হয়েছে। সেই ডামি অ্যাপটি ডিপিআই সচেতন হয় না।
  • আমরা উভয় রিলিজের মধ্যে মূল সিএসপোজ ফাইলগুলি তুলনা করেছি এবং এর অর্থপূর্ণ পার্থক্য নেই।
    • ডাব্লুপিএফ থেকে মুক্তি ছাড়াও কোনও কিছুই রেফারেন্স নেই।

আমরা বুঝতে পারি না কেন আমাদের 6.1 প্রকাশ হঠাৎ করে ডিপিআই সচেতন হয়ে উঠেছে। আমরা আর কি দেখার জন্য নিখুঁত এবং আমাদের একটি ফিক্স দরকার যা এই রিলিজটিকে ডিপিআই অজানা মোডে ফিরিয়ে দেয়। এটি আমাদের মুক্তি ধরে রেখেছে। সত্যিই কোন পয়েন্টার প্রশংসা করবে। আমরা এই সময়ে কিছু চেষ্টা করতে ইচ্ছুক।


এই প্রশ্নে রিপোর্ট করা সমস্যা সম্পর্কে :
ডিজাইনের মাধ্যমে ডিপিআই-অজানা একটি অ্যাপ্লিকেশন, হ'ল হঠাৎ (যদিও কিছু সংশোধন করার পরে, একটি সামান্য প্রকাশের আপডেটে নেতৃত্ব দেয়) - এর ইউআই সামগ্রীটি স্কেল করার জন্য উইন্ডোজ ভার্চুয়ালাইজেশনের উপর নির্ভর করে - এবং ডিপিআই-সচেতন হয় (সিস্টেম সচেতন) )।

  • অ্যাপ্লিকেশনটি app.manifest <windowsSettings> app.manifest <windowsSettings> এর একটি ব্যাখ্যার উপরেও নির্ভর করে, যেখানে ডিপিআই-সচেতনতার সংজ্ঞা নেই, ডিপিআই- app.manifest ডিফল্ট (পিছিয়ে সামঞ্জস্যের জন্য) রয়েছে।

  • ডাব্লুপিএফ অ্যাসেমব্লিতে কোনও সরাসরি উল্লেখ নেই এবং কোনও ডিপিআই-সম্পর্কিত এপিআই কল নেই।

  • অ্যাপ্লিকেশনটিতে তৃতীয় পক্ষের উপাদানগুলি (এবং সম্ভবত বাহ্যিক নির্ভরতা) অন্তর্ভুক্ত রয়েছে।

যেহেতু ডিপিআই-সচেতনতা ইউআই উপস্থাপনার একটি প্রাসঙ্গিক দিক হয়ে উঠেছে, বিভিন্ন স্ক্রিন রেজোলিউশন উপলব্ধ (এবং সম্পর্কিত ডিপিআই স্কেলিং সেটিংস) এর ফলে, বেশিরভাগ উপাদান উত্পাদক উচ্চ-ডিপিআইতে খাপ খাইয়ে নিয়েছে এবং তাদের পণ্যগুলি ডিপিআই-আওয়ার (স্কেল যখন কোনও ডিপিআই পরিবর্তন হয়) সনাক্ত করা হয়েছে) এবং ডিপিআই-আওয়ার অ্যাসেমব্লিগুলি ব্যবহার করুন (প্রায়শই ডাব্লুপিএফ অ্যাসেমব্লিগুলি সংজ্ঞায়িত করে, ডিপিআই-আওয়ার সংজ্ঞা অনুসারে)।

যখন এই প্রকল্পের (সরাসরি বা অপ্রত্যক্ষভাবে) এর মধ্যে কোনও ডিপিআই-আওয়ার উপাদানগুলির পুনর্বহাল করা হয়, তখন ডিপিআই-অজানা অ্যাপ্লিকেশনটি ডিপিআই-আওয়ার হয়ে যাবে, যখন ডিপিআই-সচেতনতা স্পষ্টভাবে অক্ষম করা হয়নি।

কোনও অ্যাসেম্বলি ডিপিআই-সচেতনতা ঘোষণা করার জন্য আরও প্রত্যক্ষ (এবং প্রস্তাবিত) পদ্ধতিটি হ'ল আবেদন ম্যানিফেস্টিতে এটি স্পষ্টভাবে ঘোষণা করা।

ভিজ্যুয়াল স্টুডিও 2017 এর আগে একটি অ্যাপ্লিকেশন ম্যানিফেস্ট সেটিংয়ের জন্য হ্যান্স প্যাসেন্টের উত্তরটি দেখুন:
উচ্চ ডিপিআই সেটিং সহ কোনও মেশিনে চালানোর জন্য কীভাবে কোনও অ্যাপ্লিকেশন কনফিগার করবেন

ভিজ্যুয়াল স্টুডিও 2015-আপডেট.1 এবং ভিজ্যুয়াল স্টুডিও 2017 app.manifest , এই সেটিংটি ইতিমধ্যে উপস্থিত রয়েছে, এটি কেবল app.manifest হওয়া দরকার। বিভাগটি সেট করুন: <dpiAware>false</dpiAware>

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>

  //(...)

  <!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
       DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need 
       to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should 
       also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->

  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</dpiAware>
    </windowsSettings>
  </application>

//(...)

</assembly>

আরও তথ্যের জন্য এই এমএসডিএন নিবন্ধগুলি দেখুন:
উইন্ডোজে হাই ডিপিআই ডেস্কটপ অ্যাপ্লিকেশন বিকাশ
কোনও প্রক্রিয়ার জন্য ডিফল্ট ডিপিআই সচেতনতা সেট করা

আর একটি পদ্ধতি হ'ল এই উইন্ডোজ এপিআই ফাংশনগুলি ব্যবহার করে প্রক্রিয়া প্রসঙ্গে ডিপিআই-সচেতনতা সেট করা:

উইন্ডোজ 7
SetProcessDPIAware

[DllImport("user32.dll", SetLastError=true)]
static extern bool SetProcessDPIAware();

উইন্ডোজ 8.1
SetProcessDpiAwareness

[DllImport("shcore.dll")]
static extern int SetProcessDpiAwareness(ProcessDPIAwareness value);

enum ProcessDPIAwareness
{
    DPI_Unaware = 0,
    System_DPI_Aware = 1,
    Per_Monitor_DPI_Aware = 2
}

উইন্ডোজ 10, সংস্করণ 1703
SetProcessDpiAwarenessContext()
(প্রতি-মনিটর ডিপিআই-সচেতনতার জন্য নির্বাচন করার সময়, Context_PerMonitorAwareV2 ব্যবহার Context_PerMonitorAwareV2 )

আরও দেখুন: মিক্সড-মোড ডিপিআই স্কেলিং এবং ডিপিআই-সচেতন এপিআই - এমএসডিএন

উইন্ডোজ 10, সংস্করণ 1809 (অক্টোবর 2018)
একটি নতুন DPI_AWARENESS_CONTEXT করা হয়েছে: DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED

জিডিআই-ভিত্তিক সামগ্রীর উন্নত মানের সাথে অজানা ডিপিআই। এই মোডটি DPI_AWARENESS_CONTEXT_UNAWARE এর অনুরূপ আচরণ করে, তবে উইন্ডোটি একটি উচ্চ-ডিপিআই মনিটরে প্রদর্শিত হবে তখন স্বয়ংক্রিয়ভাবে পাঠ্য এবং অন্যান্য জিডিআই-ভিত্তিক আদিমগুলির রেন্ডারিং মানের উন্নত করতে সিস্টেমকে সক্ষম করে।

বর্তমান থ্রেডের DPI_AWARENESS_CONTEXT হ্যান্ডেলের জন্য একটি উইন্ডোর DPI_AWARENESS_CONTEXT হ্যান্ডেলটি পুনরুদ্ধার করতে GetWindowDpiAwarenessContext() ফাংশনটি ব্যবহার করুন। তারপরে GetAwarenessFromDpiAwarenessContext() কাঠামো থেকে DPI_AWARENESS মানটি DPI_AWARENESS করতে DPI_AWARENESS GetAwarenessFromDpiAwarenessContext()

[DllImport("user32.dll", SetLastError=true)]
static extern IntPtr GetWindowDpiAwarenessContext(IntPtr hWnd);

[DllImport("user32.dll", SetLastError=true)]
static extern IntPtr GetThreadDpiAwarenessContext();

[DllImport("user32.dll", SetLastError=true)]
static extern int GetAwarenessFromDpiAwarenessContext(InPtr DPI_AWARENESS_CONTEXT);


[DllImport("user32.dll", SetLastError=true)]
static extern int SetProcessDpiAwarenessContext(ContextDPIAwareness value);

// Virtual enumeration: DPI_AWARENESS_CONTEXT is *contextual*. 
// This value is returned by GetWindowDpiAwarenessContext() or GetThreadDpiAwarenessContext()
// and finalized by GetAwarenessFromDpiAwarenessContext(). See the Docs.
enum ContextDPIAwareness
{
    Context_Unaware = ((DPI_AWARENESS_CONTEXT)(-1)),
    Context_SystemAware = ((DPI_AWARENESS_CONTEXT)(-2)),
    Context_PerMonitorAware = ((DPI_AWARENESS_CONTEXT)(-3)),
    Context_PerMonitorAwareV2 = ((DPI_AWARENESS_CONTEXT)(-4)),
    Context_UnawareGdiScaled = ((DPI_AWARENESS_CONTEXT)(-5))
}

যেহেতু ডিপিআই-সচেতনতা থ্রেড-ভিত্তিক, এই সেটিংসটি একটি নির্দিষ্ট থ্রেডে প্রয়োগ করা যেতে পারে। ডিপিআই-সচেতনতা বাস্তবায়নের জন্য একটি ইউজার ইন্টারফেসটিকে নতুন করে ডিজাইন করার সময় এটি কার্যকর হতে পারে, আরও গুরুত্বপূর্ণ কার্যকরীতার উপর ফোকাস করার সময় সিস্টেমটিকে কম গুরুত্বপূর্ণ উপাদান স্কেল করতে দেয়।

SetThreadDpiAwarenessContext
( SetProcessDpiAwarenessContext() হিসাবে একই পরামিতি SetProcessDpiAwarenessContext() )

Assemblyinfo.cs
যদি কোনও তৃতীয় পক্ষ / বাহ্যিক উপাদান, যা ডাব্লুপিএফ সমাবেশগুলি উল্লেখ করে, কোনও অ্যাপ্লিকেশনটির ডিপিআই-সচেতনতার স্থিতিটিকে নতুনভাবে সংজ্ঞায়িত করে, তাহলে এই অটোমেটিক আচরণটি অক্ষম হতে পারে, প্রজেক্ট Assemblyinfo.cs একটি প্যারামার্ট tingোকানো:

[assembly: System.Windows.Media.DisableDpiAwareness]




dpi-aware