Возвращаемый дескриптор GetPhysicalMonitorsFromHMONITOR всегда равен нулю - PullRequest
3 голосов
/ 11 мая 2009

В Media Foundation SDK есть функция GetPhysicalMonitorsFromHMONITOR что я пытаюсь реализовать с помощью C #, но безуспешно ...

В возвращенном PHYSICAL_MONITOR [] функция возвращает описание строки монитора, но по некоторым загадочным причинам дескриптор hPhysicalMonitor остается в 0.

Я сгенерировал подписи с помощью P / Invoke Interop Assistant с небольшими изменениями.

Требуется ли дальнейшая настройка структуры PHYSICAL_MONITOR или чего-либо еще?

Спасибо.

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using WindowsFormsApplication1;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public enum MC_DISPLAY_TECHNOLOGY_TYPE
        {
            MC_SHADOW_MASK_CATHODE_RAY_TUBE,

            MC_APERTURE_GRILL_CATHODE_RAY_TUBE,

            MC_THIN_FILM_TRANSISTOR,

            MC_LIQUID_CRYSTAL_ON_SILICON,

            MC_PLASMA,

            MC_ORGANIC_LIGHT_EMITTING_DIODE,

            MC_ELECTROLUMINESCENT,

            MC_MICROELECTROMECHANICAL,

            MC_FIELD_EMISSION_DEVICE,
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct PHYSICAL_MONITOR
        {
            public IntPtr hPhysicalMonitor;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string szPhysicalMonitorDescription;
        }

        #region Imports

        [DllImport("user32.dll", EntryPoint = "MonitorFromWindow")]
        public static extern IntPtr MonitorFromWindow(
            [In] IntPtr hwnd, uint dwFlags);

        [DllImport("dxva2.dll", EntryPoint = "GetMonitorTechnologyType")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetMonitorTechnologyType(
            IntPtr hMonitor, ref MC_DISPLAY_TECHNOLOGY_TYPE pdtyDisplayTechnologyType);

        [DllImport("dxva2.dll", EntryPoint = "GetMonitorCapabilities")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetMonitorCapabilities(
            IntPtr hMonitor, ref uint pdwMonitorCapabilities, ref uint pdwSupportedColorTemperatures);

        [DllImport("dxva2.dll", EntryPoint = "DestroyPhysicalMonitors")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool DestroyPhysicalMonitors(
            uint dwPhysicalMonitorArraySize, ref PHYSICAL_MONITOR[] pPhysicalMonitorArray);

        [DllImport("dxva2.dll", EntryPoint = "GetNumberOfPhysicalMonitorsFromHMONITOR")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetNumberOfPhysicalMonitorsFromHMONITOR(
            IntPtr hMonitor, ref uint pdwNumberOfPhysicalMonitors);

        [DllImport("dxva2.dll", EntryPoint = "GetPhysicalMonitorsFromHMONITOR")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetPhysicalMonitorsFromHMONITOR(
            IntPtr hMonitor, uint dwPhysicalMonitorArraySize, [Out] PHYSICAL_MONITOR[] pPhysicalMonitorArray);

        #endregion

        public Form1() { InitializeComponent(); }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Get monitor handle.
            uint dwFlags = 0u;
            IntPtr ptr = MonitorFromWindow(Handle, dwFlags);

            // Get number of physical monitors.
            uint pdwNumberOfPhysicalMonitors = 0u;
            bool b1 = GetNumberOfPhysicalMonitorsFromHMONITOR(ptr, ref pdwNumberOfPhysicalMonitors);

            if (b1)
            {
                // Get physical monitors.
                uint dwPhysicalMonitorArraySize = 0u;
                dwPhysicalMonitorArraySize = pdwNumberOfPhysicalMonitors;
                PHYSICAL_MONITOR[] pPhysicalMonitorArray = new PHYSICAL_MONITOR[dwPhysicalMonitorArraySize];

                //NOTE : Handles remain null !
                bool b2 = GetPhysicalMonitorsFromHMONITOR(ptr, dwPhysicalMonitorArraySize, pPhysicalMonitorArray);

                if (pPhysicalMonitorArray[0].hPhysicalMonitor
                    == IntPtr.Zero)
                {
                    throw new Exception("ERROR !");
                }

                // Monitor has capabilities to do that ?
                if (b2)
                {
                    uint pdwMonitorCapabilities = 0u;
                    uint pdwSupportedColorTemperatures = 0u;
                    bool b3 = GetMonitorCapabilities(
                        ptr, ref pdwMonitorCapabilities, ref pdwSupportedColorTemperatures);

                    // If yes, get technology type.
                    if (b3)
                    {
                        MC_DISPLAY_TECHNOLOGY_TYPE type = MC_DISPLAY_TECHNOLOGY_TYPE.MC_SHADOW_MASK_CATHODE_RAY_TUBE;

                        bool b4 = GetMonitorTechnologyType(ptr, ref type);
                        if (b4)
                        {
                            // Do work.
                        }
                        else
                        {
                            throw new Exception("Couldn't get monitor technology type.");
                        }
                    }
                    else
                    {
                        throw new Exception("Couldn't get monitor capabilities.");
                    }
                }
                else
                {
                    throw new Exception("The monitor doesn't have the required capabilities.");
                }

                bool b5 = DestroyPhysicalMonitors(dwPhysicalMonitorArraySize, ref pPhysicalMonitorArray);
                if (!b5)
                {
                    throw new Exception("Couldn't destroy physical monitors.");
                }
            }
            else
            {
                throw new Exception("Couldn't get number of physical monitors.");
            }
        }
    }
}

Ответы [ 3 ]

1 голос
/ 02 июня 2011

Это нормально, что значение hPhysicalMonitor равно 0. Однако в примере кода вопроса все вызовы после GetPhysicalMonitorsFromHMONITOR должны использовать ссылку hPhysicalMonitor вместо ссылки ptr. Обновленный метод Form_Load должен быть следующим:

private void Form1_Load(object sender, EventArgs e)
{
    // Get monitor handle.
    uint dwFlags = 0u;
    IntPtr ptr = MonitorFromWindow(Handle, dwFlags);

    // Get number of physical monitors.
    uint pdwNumberOfPhysicalMonitors = 0u;
    bool b1 = GetNumberOfPhysicalMonitorsFromHMONITOR(ptr, ref pdwNumberOfPhysicalMonitors);

    if (b1)
    {
        // Get physical monitors.
        uint dwPhysicalMonitorArraySize = 0u;
        dwPhysicalMonitorArraySize = pdwNumberOfPhysicalMonitors;
        PHYSICAL_MONITOR[] pPhysicalMonitorArray = new PHYSICAL_MONITOR[dwPhysicalMonitorArraySize];

        //NOTE : Handles remain null !
        bool b2 = GetPhysicalMonitorsFromHMONITOR(ptr, dwPhysicalMonitorArraySize, pPhysicalMonitorArray);

        // Monitor has capabilities to do that ?
        if (b2)
        {
            uint pdwMonitorCapabilities = 0u;
            uint pdwSupportedColorTemperatures = 0u;
            bool b3 = GetMonitorCapabilities(pPhysicalMonitorArray[0].hPhysicalMonitor, ref pdwMonitorCapabilities, ref pdwSupportedColorTemperatures);

            // If yes, get technology type.
            if (b3)
            {
                MC_DISPLAY_TECHNOLOGY_TYPE type = MC_DISPLAY_TECHNOLOGY_TYPE.MC_SHADOW_MASK_CATHODE_RAY_TUBE;

                bool b4 = GetMonitorTechnologyType(pPhysicalMonitorArray[0].hPhysicalMonitor, ref type);
                if (b4)
                {
                    // Do work.
                }
                else
                {
                    throw new Exception("Couldn't get monitor technology type.");
                }
            }
            else
            {
                throw new Exception("Couldn't get monitor capabilities.");
            }
        }
        else
        {
            throw new Exception("The monitor doesn't have the required capabilities.");
        }

        bool b5 = DestroyPhysicalMonitors(dwPhysicalMonitorArraySize, ref pPhysicalMonitorArray);
        if (!b5)
        {
            throw new Exception("Couldn't destroy physical monitors.");
        }
    }
    else
    {
        throw new Exception("Couldn't get number of physical monitors.");
    }
}
1 голос
/ 11 мая 2009

Ваше заявление:

Функция возвращает строковое описание монитора, но по некоторым загадочным причинам дескриптор hMonitor остается равным 0.

правильно. Если вы посмотрите на документы здесь , вы увидите, что hMonitor явно является параметром [in] и не будет изменен.

Обновить следующий комментарий:

Извините, не понял, что вы имели в виду физический дескриптор, возвращаемый в структуре. Вся информация, которую я могу найти по этой конкретной проблеме, указывает на то, что ваш монитор, вероятно, не полностью совместим с DDC / CI (например, здесь ).

Все ваши определения структуры выглядят хорошо для меня, основываясь на документах по MSDN для этого конкретного вызова. И действительно, заполняет описание для вас.

Какое значение для количества физических мониторов возвращается с GetNumberOfPhysicalMonitorsFromHMONITOR (pdwNumberOfPhysicalMonitors)?

Кроме того, каков размер вашей PHYSICAL_MONITOR структуры, и вы используете 32 или 64 бита?

0 голосов
/ 11 мая 2009

Монитор поддерживает эту функцию, потому что с программным обеспечением, таким как softMCCS и WinI2C / DDC, свойства возвращаются правильно.

Возвращаемое значение pdwNumberOfPhysicalMonitors равно 1, что является правильным.

Как видите, его размер равен pdwNumberOfPhysicalMonitors :

PHYSICAL_MONITOR[] pPhysicalMonitorArray = new PHYSICAL_MONITOR[dwPhysicalMonitorArraySize];

А у меня Vista 32.

Это несколько странно, потому что половина из них работает, вот уже около 4 дней я нахожусь над этим, но до сих пор нет прогресса ...

Спасибо.

...