Как я определяю истинный размер пикселя своего Монитора в.NET?

Стандарт С не допускает этого.

6.5.6 Аддитивные операторы (выделение мое)

8 Когда выражение, имеющее целочисленный тип, добавляется или вычитается из указателя, результат имеет тип операнда указателя. Если операнд-указатель указывает на элемент объекта массива , и массив достаточно велик, результат указывает на смещение элемента от исходного элемента, так что различие индексов полученного и исходного массива элементы равны целочисленному выражению. Другими словами, если выражение P указывает на i-й элемент объекта массива, выражения (P) + N (эквивалентно, N + (P)) и (P) -N (где N имеет значение n) указывают соответственно i + n-му и in-му элементам массива, если они существуют. Кроме того, если выражение P указывает на последний элемент объекта массива, выражение (P) +1 указывает один за последним элементом объекта массива, а если выражение Q указывает на один последний элемент последнего элемента массива, выражение (Q) -1 указывает на последний элемент объекта массива. Если и операнд-указатель, и результат указывают на элементы одного и того же объекта массива или один после последнего элемента объекта массива, при оценке не должно быть переполнения; в противном случае поведение не определено . Если результат указывает на один последний элемент массива, он не должен использоваться в качестве операнда оцениваемого унарного оператора *.

blockquote>

Для целей вышеизложенного указатель на отдельный объект рассматривается как указывающий на массив из 1 элемента.

Теперь ((uint8_t*)0) не указывает на элемент объекта массива. Просто потому, что указатель, содержащий нулевое значение указателя, не указывает на какой-либо объект . Сказано в:

6.3.2.3 Указатели

3 Если константа нулевого указателя преобразуется в тип указателя, результирующий указатель, называемый нулевым указателем, гарантированно сравнивается с указателем на любой объект или функцию.

blockquote>

Так что вы не можете делать арифметику с ним. Предупреждение оправдано, потому что, как упоминается во втором выделенном предложении, мы имеем дело с неопределенным поведением.

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

9
задан Peter Tate 7 January 2009 в 21:55
поделиться

4 ответа

Для размера дисплея Вы захотите Screen.PrimaryScreen.Bounds.Size (или Screen.GetBounds(myform)).

Если Вы хотите DPI, используйте свойства DpiX и DpiY Графики:

PointF dpi = PointF.Empty;
using(Graphics g = this.CreateGraphics()){
    dpi.X = g.DpiX;
    dpi.Y = g.DpiY;
}

О, ожидайте! Вы хотели фактический, держите линейку до монитора и меры, размера?! Нет. Не возможное использование любых служб ОС. ОС не знает фактических размеров монитора, или как пользователю калибровали его. Часть этой информации теоретически обнаруживаема, но это не достаточно детерминировано, чтобы ОС использовала его надежно, таким образом, это не делает.

Как работа вокруг, можно попробовать несколько вещей.

  • Можно попытаться запросить строку дисплея установленного устройства мониторинга (я не уверен, как сделать это), и посмотрите, можно ли проанализировать разумный размер из этого. Например, монитором мог бы быть "ValueBin E17p", и Вы могли бы вывести, что это - 17" мониторов от этого. Конечно, эта строка дисплея, вероятно, будет "Монитором Plug and Play". Эта схема является довольно поверхностной в лучшем случае
  • Вы могли спросить пользователя, какой монитор размера они имеют. Возможно, они будут знать.

После того как Вы знаете (или думайте, что Вы знаете), диагональный размер монитора, необходимо найти его физическое соотношение сторон. Снова, несколько вещей:

  • Предположите, что текущая попиксельная пропорция соответствует физическому соотношению сторон монитора. Это предполагает, что (A), пользователь выбрал разрешение, которое идеально для их монитора, и что (B) монитор имеет квадратные пиксели. Я не знаю о текущем ориентированном на потребителя компьютерном мониторе, который не имеет квадратных пикселей, но более старые сделали и более новые могли бы.
  • Спросите пользователя. Возможно, они будут знать.

После того как Вы знаете (или думайте, что Вы знаете), каковы диагональный размер монитора и физическое соотношение сторон, затем Вы можно вычислить, это - физическая ширина и высота. A2 + B2 = C2, таким образом, несколько вычислений дадут его Вам хороший:

Если Вы узнали, что это - 17-дюймовый монитор, и его текущее разрешение составляет 1280 x 1024:
12802 + 10242 = 2686976
Sqrt (2686976) = 1639.1998047828092637409837247032
17 дюймов * 1280 / 1639.2 = 13,274768179599804782820888238165 дюймов
17 дюймов * 1024 / 1639.2 = 10,619814543679843826256710590532 дюймов

Это помещает физическую ширину в 13,27 дюймов и физическую высоту на уровне 10,62 дюймов. Это делает пиксели 13,27 дюймами / 1280 = 10,62 дюймов / 1024 = 0,01037 дюйма или приблизительно 0,263 мм.

Конечно, все это недопустимо, если у пользователя нет подходящего разрешения, монитор имеет дурацкие неквадратные пиксели, или это - более старый аналоговый монитор, и средства управления не корректируются правильно для дисплея для заполнения всего физического экрана. Или хуже, это мог быть проектор.

В конце можно быть лучшими от выполнения калибровочного шага, где у Вас есть пользователь, на самом деле содержат линейку до экрана и измеряют размер чего-то для Вас. Вы могли:

  • Сделайте, чтобы пользователь щелкнул мышью на любых двух точках дюйм (или сантиметр) независимо.
  • Потяните поле на экране и сделайте, чтобы пользователь нажал стрелки вверх и вниз для регулирования его высоты и левых и правых стрелок для корректировки его ширины, пока поле не составит точно один дюйм (или сантиметр) квадрат согласно их линейке.
  • Потяните поле на экране и сделайте, чтобы пользователь сказал Вам, сколько дюймов/сантиметры это находится в каждом размере.

Независимо от того, что Вы делаете, не ожидайте, что Ваши результаты будут на 100% точны. Существует слишком много факторов в действии для Вас (или пользователь) для получения, это точно исправляет, каждый раз.

Знайте, что 96 точек на дюйм обычно достаточно близки к точному. Современные пиксели на неспроектированных экранах, все склонны быть приблизительно 0,25 мм, плюс-минус, таким образом, Вы обычно заканчиваете приблизительно с 100 физическими пикселями на дюйм, плюс-минус, если монитор установлен на свое родное разрешение. (Конечно, это - огромное обобщение и не относится ко всем мониторам. ПК Eee, например, имеют пиксели приблизительно 0,19 мм в размере, если я помню спецификации правильно.)

28
ответ дан 4 December 2019 в 07:15
поделиться

извините, Вы имеете к P/Invoke для этой информации.

Вот ссылка, которую я использовал для него только что: http://www.davidthielen.info/programming/2007/05/get_screen_dpi_.html

1
ответ дан 4 December 2019 в 07:15
поделиться

GetDeviceCaps может быть P/Invoke'd для получения некоторых чисел, но я никогда не знал, что числа что защищены...

1
ответ дан 4 December 2019 в 07:15
поделиться

Можно проверить просто вручную вычисление от размера экрана

cos(45)*LCD_SCREEN_DIAGONAL_IN_INCHES/sqrt(HORZ_RES^2 + VERT_RES^2)

Это дало бы Вам пиксельную ширину в дюймах

1
ответ дан 4 December 2019 в 07:15
поделиться