движения на мишката за фонова нишка, създадени прозорци

Чудя се дали е възможно 1) Хостинг на фонова нишка, създадена прозоречна форма вътре в основната нишка на приложението, създадена прозоречна форма? или 2) Отделете нишката, която обработва движенията на мишката, от нишката, която рисува приложение за формуляри на Windows?

Знам, че тези въпроси звучат много налудничаво, но откривам, че се сблъсквам с особен проблем и приветствам съвета да можем да заобиколим този проблем, въпреки че не мисля, че можем лесно да се разделим с Windows Forms и да използваме различни потребителски технологии.

Нашият софтуерен екип пише някои плъгини за приложение за Windows на трета страна. ТАКА че ние предоставяме основна основна форма, която хоства куп потребителски контроли за тях, използвайки техния API и те ги хостват в своя собствена Windows форма. Понастоящем всички потребителски интерфейси се създават в основната нишка на приложението, така че те си взаимодействат добре. Много от нашите потребителски контроли, които предоставяме, имат диаграми на system.windows.forms.datavisualisation, които се рисуват на живо от данните, които приложението извлича. Един от проблемите, които имаме, е, че когато потребителят движи мишката неравномерно, дисплеят спира да се актуализира, тъй като цялото рисуване на графиките (GDI+) се извършва в главната нишка (ние използваме фонови нишки и TPL за извличане и изчисляване на данни, но рисуването се прави на основната нишка). Така че се чудя дали е възможно да накарам цялото gdi+ рисуване на тези диаграми да се извършва в нишка, различна от основната нишка на приложението, така че рисуването да продължи и все още можем да получаваме въведени данни за движение на мишката и щраквания за потребителски взаимодействия, но хаотична мишка движенията не могат да наводнят опашката със съобщения и да спрат рисуването на gdi+ на потребителските контроли.

Всякаква помощ специално, специално указатели към съответните API или статии, демонстриращи техники, ще бъдат много оценени. Благодаря ти.


person Comic Book Guy    schedule 30.05.2014    source източник
comment
анонимното гласуване против е гадно и е страхливо. :-)   -  person Comic Book Guy    schedule 30.05.2014
comment
Съгласен, с +1 за компенсация :)   -  person A.J. Uppal    schedule 30.05.2014


Отговори (1)


Зависи от причината за забавянето, когато тегленето приключи.

Първо, трябва да оптимизирате вашите процедури за рисуване, може би рисувате целия формуляр/контрола при всяко извикване на OnPaint? Ако случаят е такъв, тогава трябва да начертаете отново само невалидната област, това ще ускори много нещата.

В противен случай, ако все още трябва да направите чертежа в друга нишка, тогава не можете да го направите директно, потребителският интерфейс може да бъде модифициран само в главната нишка, но можете да използвате растерно изображение като буфер извън екрана и след това да рисувате отново от него.

За да направите това, когато вашата контрола е създадена, вие създавате и растерно изображение на размера на вашите контроли (също така трябва да се погрижите за преоразмеряването). Така че, когато трябва да се направи някаква промяна във външния вид на вашата контрола, нарисувайте я в растерното изображение, можете да го направите в друга нишка и след това обезсилете актуализираната област на вашата контрола.

И накрая, в OnPaint на вашата контрола просто изпъква от това растерно изображение към вашата контрола и само невалидната област, това извикване все още ще се извършва в главната нишка, но ви уверявам, че всяка машина днес е в състояние да изпразва много големи изображения за милисекунди.

Като пример, да предположим, че имате контрола, където рисувате градиентен фон и кръг.

Обикновено ще рисувате директно върху контролната повърхност чрез графичен обект всеки път, когато искате да актуализирате нещо, да кажем фона, така че, за да го промените, ще нарисувате целия фон и своя кръг върху него.

За да направите това във фонов режим, ако сте създали растерно изображение като буфер извън екрана, не рисувате на повърхността, рисувате върху растерното изображение в друга нишка (получавайки графичен обект от него) и след това обезсилвате актуализираната област на контролата . Когато направите невалидна, ще бъде извикана зоната OnPaint и след това можете да преминете от това растерно изображение към повърхността на контролите.

В тази стъпка спечелихте малко или никаква скорост, но нека разширим нашия пример. Да предположим, че рисувате много сложна контрола с много извиквания към DrawImage, DrawCircle и т.н. Когато мишката се движи над контролата, малките области се анулират и при всяко извикване на OnPaint ще рисувате всички „слоеве“, съставляващи невалидната област , може да има много равенства, ако, както казахме, контролът е много сложен.

Но ако сте начертали към растерно изображение външния вид на вашите контроли, при всяко извикване на OnPaint вие просто ще изчертаете съответната област от растерното изображение към контролата, както виждате, че намалявате повикванията от много чертания до просто блит.

Надяваме се, че изяснява идеята.

person Gusman    schedule 30.05.2014
comment
Благодаря за съвета. ние изобразяваме във фонови буфери, като използваме фонова нишка и блит, както споменахте за персонализирани нарисувани екрани, заедно със селективно обезсилване, въпреки това, основният формуляр на Windows има двойно буферирано свойство, зададено на истина и мисля, че всички потребителски контроли също, може би това е контрапродуктивно, имахте ли съвет, ако това означава, че има твърде много задни буфери? също така е направено много рисуване моите контроли на Windows Forms и mscharts. Не съм сигурен как мога да ги накарам да рисуват върху растерно изображение и блести в изключение от използването на свойството двойно буферирано възможно ли е това? - person Comic Book Guy; 30.05.2014
comment
Разширен отговор за изясняване на концепцията. - person Gusman; 30.05.2014