Как избежать изменения размера MDIParent формы
Я разрабатываю приложение Windows Form. У меня есть MDIParent форма, которая загружается в развернутом состоянии, а также загружает его дочерние формы в развернутом состоянии. Однако, когда я открываю OpenFileDialog или любой объект для чтения данных, MDIParent уменьшается до меньшего размера со всеми его формами и элементами управления.
Это решение Открытие дочерней формы приводит к тому, что mdiform меняет размер, а сжатие не применяется / не работает в моей ситуации.
Также это решение https://support.microsoft.com/en-nz/help/967173/restoring-a-maximized-or-minimized-mdi-parent-form-causes-its-height-t не работает для меня.
Немного предыстории: я видел такое поведение почти во всех моих приложениях WinForm, но я никогда не стремился разобраться в этом. Мне удалось сузить круг причин, о которых говорилось выше, когда я начал их расследовать. Некоторые посты описывают это как ошибку Windows, но она существует до тех пор, пока разрешение экрана стало больше 1024 (VS 2010) для моего случая. Я надеялся, что это не просто ошибка Windows...
1 ответ
Я надеялся, что это не просто ошибка Windows...
Особенность, не ошибка, но она не очень нравится программистам Winforms. Примечательно, что за последние несколько месяцев было несколько вопросов о таинственной усадке окон. Я думаю, что это связано с выпуском издания Win10 Fall Creators. Он имеет глубокие изменения в устаревшем слое Win32 API, и они вызвали много потрясений.
В вашем конкретном случае "функция" включается расширением оболочки. Они внедряются в ваш процесс, когда вы используете OpenFileDialog. Тот, кто делает это, очень, очень злой и делает то, что расширение оболочки не должно делать абсолютно никогда. Он вызывает SetProcessDPIAware (). Примечательным является то, что он мог быть написан на WPF, у него очень хитрый бэкдор, чтобы объявить себя dpiAware. Достаточно просто загрузить сборку PresentationCore. Но в остальном код WPF не ограничивается, любой код может сделать это, и это могло быть незамеченным в течение длительного времени.
Один из способов отыскать это злое расширение - использовать утилиту автозапуска SysInternals. Это позволяет вам выборочно отключать расширения. Но есть и способ программиста, вы можете отладить это в VS.
Используйте "Проект"> "Свойства"> вкладка "Отладка"> установите флажок "Включить отладку собственного кода". Назван слегка по-другому в старых версиях VS, кстати. Затем Debug > New Breakpoint > Function Breakpoint. Название функции = user32!SetProcessDPIAware
Язык = C
, Вы можете выполнить это в приложении WPF, которое ничего не делает, чтобы убедиться, что все настроено правильно. Для полноты вы также можете добавить точку останова для SetProcessDPIAwareness, нового варианта.
Нажмите клавишу F5, чтобы начать отладку и вызвать вызов OpenFileDialog.ShowDialog(). Теперь должна быть достигнута точка останова, используйте Debug > Windows > Call Stack, чтобы посмотреть трассировку стека. Обычно в вашем случае вы не увидите ничего очень узнаваемого, поскольку злой код находится в DLL, для которой у вас нет PDB. Но имя и расположение DLL (видимые в Debug > Windows > Modules) должны быть полезны для определения человека, которому нужно сообщить об ошибке. Удалите его, если вы можете жить без него.
И последнее, но не менее важное: становится очень важно начать создавать приложения Winforms, которые являются dpiAware, поэтому такая ошибка никогда не может быть байтовой. Вы запускаете это, объявляя ваше приложение dpiAware, поэтому виртуализация DPI отключена. Кроме того, все, что вам нужно сделать в своем коде, чтобы обеспечить правильное масштабирование дизайна пользовательского интерфейса.