Я пытаюсь создать интерактивные обои для рабочего стола Windows 7/8 в Mono / .Net. Я обновляю обои только тогда, когда они меняются, и я использую SystemParametersInfo () в user32.dll для этого. Мой код выглядит так:
const int SPI_SETDESKWALLPAPER = 20;
const int SPIF_UPDATEINIFILE = 0x01;
const int SPIF_SENDWININICHANGE = 0x02;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
public static void Set2(string path)
{
SystemParametersInfo(SPI_SETDESKWALLPAPER,0,path,SPIF_UPDATEINIFILE |
SPIF_SENDWININICHANGE);
}
Несмотря на то, что я обновляю его только тогда, когда это необходимо, мои обои по-прежнему очень не отвечают. Используя секундомер, я обнаружил, что SystemParametersInfo занимает около 1 секунды для перезагрузки обоев. Использование второго потока не сделает его более отзывчивым, так как для обновления обоев потребуется столько же времени. Похоже, это в основном не зависит от размера растрового изображения. Простое обновление изображения в месте пути не меняет обои, если не вызывается SystemParameterInfo.
Из того, что я понимаю, user32.dll использует неуправляемый код, а SystemParameterInfo загружает изображение в память. Однако должен быть какой-то указатель на него, иначе Windows не найдет его снова при рендеринге рабочего стола.
Короче говоря, я хотел бы знать, возможно ли получить доступ к этому указателю. Размер моего изображения не меняется, поэтому я могу просто перезаписать его, не беспокоясь о распределении памяти. Таким образом, я мог бы избежать дорогостоящего метода SystemParametersInfo.
Пожалуйста, скажите мне, если я что-то неправильно понял, потому что я немного потерян, когда дело доходит до Windows. Если вы знаете решение, которое требует небезопасного кода или кода C ++, это тоже подойдет. Любые комментарии или обсуждения будут оценены.
Спасибо.
РЕДАКТИРОВАТЬ:
Теперь я знаю, что вызывает замедление.
SystemParametersInfo(SPI_SETDESKWALLPAPER,0,path,SPIF_UPDATEINIFILE |
SPIF_SENDWININICHANGE);
Последний аргумент указывает, будет ли обновляться Windows-файл Windows. Во всех обсуждавшихся здесь ветках об изменениях обоев было установлено значение 3, которое, по-видимому, является основным ini-файлом Windows. В подобных случаях, когда фон перезагружается много раз в секунду, это значение должно быть установлено равным 0, поскольку фактический путь к изображению не изменяется.
После этого я могу легко достичь 100 кадров в секунду.
Поскольку это почти наверняка единственный поток в StackOverflow, который упоминает об этом, и, поскольку я уверен, что другие люди будут заинтересованы в том, чтобы знать об этом тоже (это не очень объяснено в документах библиотеки Microsoft Windows), я добавил это «открытие» к названию, чтобы люди могли искать и находить его.
Теперь это не решение, хотя. Меня все еще интересует фактический указатель памяти на рабочую копию обоев. Используя его, не нужно пропускать все изображение, но вместо этого можно выборочно изменять только те байты изображения, которые действительно меняются между кадрами, как это делается в большинстве систем с графическим интерфейсом.
Задача ещё не решена.