Zilele trecute lucram la o chestie (în timpul liber) folosind WPF. Experimentam un pic cu Speech recognition-ul din Vista și am avut la un moment dat nevoie de controlul WebBrowser din Windows Forms (experimentul meu era să văd în cât timp pot să fac în .NET un Browser activat de voce).
Cu toate că lucrez în Live Search (mai exact în infrastructură) și activitățile mele zilnice implică mult hardware, când ajung seara acasă mai citesc câte ceva din anumite cărți de IOC și îmi mai vin idei pe care încerc să le aduc la viață în timpul liber (da, am și timp liber).
Ideea principală a post-ului era să arăt cum se poate folosi un control din Windows Forms într-o aplicație WPF. Aceasta e ideea principală, pentru că speech recognition-ul e foarte ușor.
SpeechRecognizer spRecon = new SpeechRecognizer(); spRecon.SpeechRecognized += spRecon_SpeechRecognized; … private void spRecon_SpeechRecognized(object sender, SpeechRecognizedEventArgs e) { MessageBox.Show(e.Result.Text + ” — am inteles bine?”); }
Ca o paranteză, dacă tot suntem aici, încercați asta:
SpeechSynthesizer synth = new SpeechSynthesizer(); synth.Speak(“Wussup?”);
că tot mi-am adus aminte cum pe aici e la modă spam-ul la telefon folosind citirea software a unui text.
Revenind la WPF și Windows Forms, sunt o serie de controale de Windows Forms care nu se regăsesc în WPF, dar nici nu este vreo alternativă de a simula comportamentul acestora folosind alte controale. Printre acestea, se numără PropertyGrid, WebBrowser, ErrorProvider, HelpProvider și altele care au mai mult sau mai puțin echivalent sau care au sau nu relevanță în spațiul WPF.
Controlul WebBrowser poate fi simulat folosind Frame și încărcând un HTML. Dar pentru a accesa programatic elemente din arborele HTML a paginii, WebBrowser este singura variantă.
Cum poate fi folosit WebBrowser într-o fereastră WPF?
<Grid>
<WindowsFormsHost>
<wf:WebBrowser Url=“http://www.iaci.ro”>
</wf:WebBrowser>
</WindowsFormsHost>
</Grid>
după ce în prealabil ați definit spațiul wf:
<Window x:Class=“LoudMouthBrowser.MainWnd” xmlns=“http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=“http://schemas.microsoft.com/winfx/2006/xaml” Title=“Main” xmlns:wf=“clr-namespace:System.Windows.Forms; assembly=System.Windows.Forms”>
Banal. Mai ușor decât speech-recognition-ul. Dar de fiecare dată e un dar.
Trebuie avut în vedere un lucru aparent neimportant, dar care poate complica treburile în mod barbar: handler-e de ferestre. Dacă o fereastră are și conținut WPF și Windows Forms, ambele zone au handler-e separate (hwnd), gestionate separat. În aplicațiile Windows clasice, fiecare control este o “fereastră” adică este proprietar pe o zonă de ecran spre deosebire de WPF, unde există un singur hwnd pentru întreg “ansamblul artistic” și motorul de randare se ocupă de restul problemelor. Acest model face posibilă randarea conținutului unui obiect vizual în afara limitelor sale de dimensiune.
Din cauza asta, orice control Windows Forms poziționat pe o fereastră WPF va fi întotdeauna deasupra restului controalelor, indiferent de z-index (asta ca să nu creadă cineva că e un bug). Este de fapt chestiunea precedentă. Controlul Windows Forms va fi o fereastră separată care va fi tot timpul randată deasupra ferestrei WPF.
Dacă acest control este o fereastră separată, nu este randat de motorul WPF. Deci, surpriză când se încearcă proprietăți de transformare sau opacitate. Din nou, faptul că nu au nici un efect se datorează faptului că respectivul control Windows Forms este de fapt altă fereastră care nu are nici o legătură cu WPF-ul. Asta ca să vă salveze câteva căutări pe Live search (right on!
) și câteva postări pe forumuri întrebând de ce WebBrowser-ul făcut cu WPF nu se învârte după o animație în ritmul unei melodii.
P.S.: Știu. Codul arată ca și cum nu ar arăta. Working on it.

4 Comments
O mica corectura pentru post. Visual Studio 2008 SP1 pune la dispozitia dezvoltatorului si controlul de WebBrowser pentru WPF.
Da, .NET fx 3.5 SP1 are WebBrowser bazat pe WPF.
Anyways, WebBrowser este doar un exemplu, care poate fi generalizat la orice control Windows Forms.
Nu am reusit sa fac acest lucru sa ruleze:
SpeechSynthesizer synth = new SpeechSynthesizer();
synth.Speak(“Wussup?”);
nu gaseste clasa. System.Speech.Synthesis nu?
Add Reference -> .NET -> System.Speech
using System.Speech.Synthesis;
Post a Comment