سؤال

أحاول تحديد كيف يمكنني اكتشاف قيام المستخدم بتغيير حجم خط Windows من الخطوط العادية إلى الخطوط الكبيرة جدًا، ويتم تحديد حجم الخط عن طريق تنفيذ الخطوات التالية على جهاز يعمل بنظام التشغيل Windows XP:

  1. انقر بزر الماوس الأيمن على سطح المكتب وحدد خصائص.
  2. انقر فوق علامة التبويب المظهر.
  3. حدد حجم الخط:الخطوط العادية/الكبيرة/الخطوط الكبيرة جدًا

ما أفهمه هو أن تغيير حجم الخط يؤدي إلى تغيير DPI، لذا إليك ما جربته حتى الآن.


هدفي:

أريد الكشف عن متى حجم الخط في ويندوز لقد تغير من الخطوط العادية إلى الخطوط الكبيرة أو الكبيرة جدًا واتخذ بعض الإجراءات بناءً على تغيير حجم الخط هذا.أفترض أنه عندما يتغير حجم خط Windows، ستتغير DPI أيضًا (خاصة عندما يكون الحجم عبارة عن خطوط كبيرة جدًا


ما حاولت حتى الآن:

تصلني عدة رسائل منها:WM_SETTINGCHANGE، WM_NCCALCSIZE، WM_NCPAINT، إلخ...ولكن لا تعد أي من هذه الرسائل فريدة بالنسبة للموقف عندما يتغير حجم الخط، بمعنى آخر، عندما أتلقى رسالة WM_SETTINGSCHANGE أريد معرفة ما الذي تغير.

من الناحية النظرية، عندما أقوم بتعريف OnSettingChange ويطلق عليه Windows، يجب أن يخبرني lpszSection بالقسم المتغير، وهذا يعمل بشكل جيد، ولكن بعد ذلك أتحقق من القسم المحدد عن طريق استدعاء SystemParametersInfo وقم بتمرير الإجراء SPI_GETNONCLIENTMETRICS، وأنتقل خلاله أتأكد أنا ومصحح الأخطاء من مراقبة البيانات الموجودة في NONCLIENTMETRICS التي تم إرجاعها بحثًا عن أي تغييرات في الخط، ولكن لم يحدث أي شيء.

حتى لو لم ينجح ذلك، فلا يزال يتعين عليّ التحقق من DPI عند تغيير الإعدادات.لا أهتم حقًا بالتفاصيل الأخرى، في كل مرة أحصل فيها على رسالة WM_SETTINGCHANGE، سأقوم فقط بفحص DPI وتنفيذ الإجراءات التي أرغب في تنفيذها، لكنني غير قادر على الحصول على DPI للنظام أيضًا.

لقد حاولت الحصول على DPI عن طريق استدعاء الطريقة GetSystemMetrics أيضًا لكل وحدة تحكم في المجال DC:

Dekstop DC->GetDeviceCaps LOGPIXELSX/LOGPIXELSY نافذة DC->GetDeviceCaps LOGPIXELSX / LOGPIXELSY DC->GetDeviceCaps الحالي LOGPIXELSX / LOGPIXELSY

حتى إذا قمت بتغيير DPI في نافذة خصائص الرسم، فإن هذه القيم لا تُرجع أي شيء مختلف، بل تظهر دائمًا 96.

هل يمكن لأي شخص أن يساعدني في معرفة هذا من فضلك؟ما الذي يجب أن أبحث عنه؟أين يجب أن أنظر؟

afx_msg void CMainFrame::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
    int windowDPI = 0;
    int deviceDPI = 0;
    int systemDPI = 0;
    int desktopDPI = 0;
    int dpi_00_X = 0;
    int dpi_01_X = 0;
    int dpi_02_X = 0;
    int dpi_03_X = 0;

    CDC* windowDC = CWnd::GetWindowDC(); // try with window DC
    HDC desktop = ::GetDC(NULL); // try with desktop DC
    CDC* device = CWnd::GetDC(); // try with current DC
    HDC hDC = *device; // try with HDC
    if( windowDC )
    {
        windowDPI = windowDC->GetDeviceCaps(LOGPIXELSY); 
        // always 96 regardless if I change the Font 
        // Size to Extra Large Fonts or keep it at Normal

        dpi_00_X = windowDC->GetDeviceCaps(LOGPIXELSX); // 96
    }

    if( desktop )
    {
        desktopDPI = ::GetDeviceCaps(desktop, LOGPIXELSY); // 96
        dpi_01_X = ::GetDeviceCaps(desktop, LOGPIXELSX); // 96
    }

    if( device )
    {
        deviceDPI = device->GetDeviceCaps(LOGPIXELSY); // 96
        dpi_02_X = device->GetDeviceCaps(LOGPIXELSX); // 96
    }

    systemDPI = ::GetDeviceCaps(hDC, LOGPIXELSY); // 96
    dpi_03_X = ::GetDeviceCaps(hDC, LOGPIXELSX); // 96

    CWnd::ReleaseDC(device);
    CWnd::ReleaseDC(windowDC);
    ::ReleaseDC(NULL, desktop);
    ::ReleaseDC(NULL, hDC);

    CWnd::OnWinSettingChange(uFlags, lpszSection);
}

تُرجع DPI دائمًا 96، لكن تغييرات الإعدادات تصبح سارية المفعول عندما أقوم بتغيير حجم الخط إلى Extra Large Fonts أو إذا قمت بتغيير DPI إلى 120 (من خصائص الرسومات).

هل كانت مفيدة؟

المحلول

[تحرير بعد إعادة القراءة] أنا متأكد تقريبًا من أن التغيير إلى "الخطوط الكبيرة" لا يؤدي إلى تغيير DPI، بل هو إعداد السمة.يجب أن تكون قادرًا على التحقق من خلال تطبيق تغيير "الخطوط الكبيرة" ثم فتح خصائص العرض المتقدمة حيث يوجد إعداد DPI، ويجب أن يظل عند 96 نقطة في البوصة.


من المفترض أن يتطلب تغيير DPI إعادة التشغيل.ربما لم يتم نشر الإعداد إلى مكان يمكن لـ GetDeviceCaps استرداده فيه؟

ربما حاول تغيير إعداد لا يتطلب إعادة التشغيل (ربما الدقة) ثم انظر ما إذا كان بإمكانك اكتشاف التغيير.إذا أمكن، فمن المحتمل أن تكون إجابتك هي أنه لا يمكنك اكتشاف تغيير DPI إلا بعد إعادة التشغيل.

نصائح أخرى

عندما تقوم باستدعاء GetDeviceCaps() على Desktop DC، هل ربما تستخدم DC الذي قد يتم تخزينه مؤقتًا بواسطة MFC، وبالتالي يحتوي على معلومات قديمة؟هل تقوم بإجراء استدعاء GetDeviceCaps() بشكل متزامن من داخل معالج OnSettingsChange الخاص بك؟أستطيع أن أرى كيف يمكن لأي من هذين الأمرين أو كليهما أن يمنحك نسخة قديمة من DPI.

ريمون تشين كتب عن هذا وكان حله يبدو هكذا (لاحظ أنني أضفت ::المشغلين لتجنب استدعاء مغلفات MFC لواجهات برمجة التطبيقات):

int GetScreenDPI()
{
  HDC hdcScreen = ::GetDC(NULL);
  int iDPI = -1; // assume failure
  if (hdcScreen) {
    iDPI = ::GetDeviceCaps(hdcScreen, LOGPIXELSX);
    ::ReleaseDC(NULL, hdcScreen);
  }
  return iDPI;
}

لدي حدس أن WM_THEMECHANGE سوف يعتني بك.ومع ذلك، ليس لديها أي تلميح حول ما تغير.سيتعين عليك استخدام OpenThemeData وتخزين الإعدادات الأولية مؤقتًا، ثم المقارنة في كل مرة تتلقى فيها الرسالة.

ربما لا تحتاج إلى الاهتمام بما تغير، ألا يمكنك أن يكون لديك روتين تخطيط للأغراض العامة يضبط النموذج/الحوار/أي شيء من خلال أخذ كل شيء في الاعتبار ويفترض البدء من الصفر؟

أي المشكلات التي تسعى إلى حلها؟

يرى http://msdn.microsoft.com/en-us/library/ms701681(VS.85).aspx ، وهذا موضح هناك (اقتباس:"إذا لم تقم بإلغاء تحجيم عدد النقاط في البوصة، فسيقوم هذا الاستدعاء بإرجاع القيمة الافتراضية البالغة 96 نقطة في البوصة.")

لا أعتقد أن عرض DPI يتغير عندما يتغير حجم الخط.من المحتمل أن يقوم Windows بإرسال ملف WM_PAINT و WM_NCPAINT الرسائل إلى جميع النوافذ المفتوحة، ويعيدون رسم أنفسهم باستخدام خط النظام الحالي (الكبير الآن).

انظر إلى هذه القيم في التسجيل:

ويندوز إكس بي الموضوع HKCU \\ البرمجيات \\ مايكروسوفت \\ ويندوز \\ الإصدار الحالي \\ ثيمي ماناجر \\ اسم الحجم القيم المحتملة:الحجم العادي والخطوط الكبيرة والخطوط الكبيرة هذه القيم هي لغة مستقلة.

ويندوز كلاسيك الموضوع HKCU \ لوحة التحكم \ المظهر \ الحالي القيم المحتملة:ويندوز كلاسيك، ويندوز كلاسيك (كبير)، ويندوز كلاسيك (كبير جدا)، ويندوز قياسي، ويندوز قياسي (كبير)، ويندوز قياسي (كبير جدا) لاحظ أن هذه القيم هي تعتمد على اللغة.

نظام التشغيل Windows Vista لا يدعم هذه الميزة.إذا أردنا خطًا أكبر، فما عليك سوى تغيير إعداد DPI.في هذه الحالة، يجب أن يعمل برنامج GetDeviceCaps.

أتمنى أن يساعدك هذا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top