Я работаю над кодовой базой (1999), у которой есть раздражающая ошибка, при которой прокрутка в некоторых элементах GUI неправильно перерисовывается, когда окно помещается на непервичное монитор.Создание зависимого от окна DeviceContext на нескольких мониторах
Насколько я могу разобраться (не очень хорошо знакомы с API-интерфейсами Windows), проблема заключается в том, что код извлекает DeviceContext для рисования с использованием GetDC(hwnd)
, который из того, что я могу сделать из документов, получает DC для только первичный монитор (но документы не очень понятны, TBH).
Я сумел сделать вещи на экране, используя в основном:
RECT rect;
GetWindowRect(hwnd, &rect);
HMONITOR monitor = MonitorFromRect(&rect, MONITOR_DEFAULTTOPRIMARY);
MONITORINFOEX minfo;
minfo.cbSize = sizeof(MONITORINFOEX);
GetMonitorInfo(monitor, &minfo);
HDC = CreateDC(NULL, minfo.szDevice, NULL, NULL);
Это получает вещи, сделанные в нужный монитор, но приложение явно ожидает то, что это окно-родственник, потому что все заканчивается в в верхнем левом углу рабочего стола, а не в окне.
Теперь мой поисковик, похоже, указывает, что выполнение кода краски дважды с использованием EnumDisplayMonitors(GetDC(), &rect, PaintCallback, NULL)
должно делать правильные вещи. К сожалению, мой код не является C или C++. Это изображение SmallTalk (и поддержка закончилась 15 лет назад или около того, поэтому жалоба на поставщика отсутствует), и я просто не уверен, что обработка изображений происходит в коде, к которому у меня есть доступ, или если он достаточно глубок в кишки SmallTalk, к которым я не могу добраться.
Таким образом, мой вопрос: возможно ли создать DC, относящийся к клиентской области моего окна (возможно, путем настройки DC из CreateDC)? Я понимаю, что это, вероятно, сломается, если окно оседлает два монитора, но это, по крайней мере, менее разрушено, чем текущее состояние вещей.
UPDATE:
мне удалось запустить код рендеринга дважды, используя EnumDisplayMonitors
, но врезается в странных отношениях (что, скорее всего, проблема SmallTalk, компилятор старый и своеобразных, но отладки кода это глубоко в стеке проблематично).
Чтобы ответить на комментарии: Я думаю, что код в принципе хочет рисовать на окнах, да. Объекты SmallTalk, представляющие различные элементы GUI, несут вокруг оконных дескрипторов, которые используются для создания контроллеров домена с GetDC(hwnd)
, так что это достаточно просто. Так звучит GetDC(hwnd)
должно получить DC, который делает правильные вещи, в данном случае; может быть, что ST-код кэширует DC-файлы где-то, и GetDC
вернет другой DC, когда окно будет перемещено на другой экран (что звучит правдоподобно из моего поверхностного знания об этом).
Похоже, вы хотите нарисовать какое-то окно. Используйте 'FindWindow' для получения дескриптора окна или используйте утилиту Spy ++ в Visual Studio, чтобы найти дескриптор окна. Создайте DC: 'HDC hdc = GetDC (hwnd)' и вызовите 'ReleaseDC (hwnd, hdc)' по завершении. Но это, конечно, дешевый взлом, ваши рисунки будут удалены очень быстро. Почему бы вам не сделать это правильно, создав собственное окно? –
Я не думаю, что проблема связана с самим GetDC. Возможно, есть также код, который использует GetClientRect/GetWindowRect, и координаты берутся относительно основного экрана. – VuVirt