Access webcam in silverlight returning false - wpf

I've done a Silverlight application that access my web cam.
Code:
public MainPage()
{
InitializeComponent();
if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
{
snapshot.Visibility = Visibility.Collapsed;
src.Start();
}
// Event Wiring
//cameraButton.Click += new RoutedEventHandler(cameraButton_Click);
photoButton.Click += new RoutedEventHandler(photoButton_Click);
saveButton.Click += new RoutedEventHandler(saveButton_Click);
// Setup Capture Source
cameraBrush.SetSource(src);
}
Problem:
The function below always return false. I try to run in debug mode and in release mode, but without success.
if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
{
snapshot.Visibility = Visibility.Collapsed;
src.Start();
}
Can someone help me ?

You need to be in Release mode its must. No debugger attached. https://stackoverflow.com/a/9258569/413032
What CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices(); returns?

Related

MVC5 DisplayModeProvider registration problems

so I have an mvc 5 application with 3 display modes, desktop (default), mobile, and tablet. I'm using WURFL to figure out devices. Here's the code called from global.cs to register:
public static void RegisterDisplayModes(IList<IDisplayMode> displayModes){
var datafile = HttpContext.Current.Server.MapPath(WurflDataFilePath);
var configurer = new InMemoryConfigurer().MainFile(datafile);
var manager = WURFLManagerBuilder.Build(configurer);
HttpContext.Current.Cache[WURFLMANAGER_CACHE_KEY] = manager;
bool mobileEnabled = ConfigurationManager.AppSettings["EnableMobileSite"] == "true";
bool tabletEnabled = ConfigurationManager.AppSettings["EnableTabletSite"] == "true";
var modeDesktop = new DefaultDisplayMode("") {
ContextCondition = (c => c.Request.IsDesktop())
};
var modeMobile = new DefaultDisplayMode("mobile"){
ContextCondition = (c => c.Request.IsMobile())
};
var modeTablet = new DefaultDisplayMode("tablet"){
ContextCondition = (c => c.Request.IsTablet())
};
displayModes.Clear();
if (mobileEnabled) displayModes.Add(modeMobile);
if (tabletEnabled) displayModes.Add(modeTablet);
displayModes.Add(modeDesktop);
}
I'm using some extension methods to HttpRequestBase, as discussed in http://msdn.microsoft.com/en-us/magazine/dn296507.aspx:
public static bool IsDesktop(this HttpRequestBase request){
return true;
}
public static bool IsMobile(this HttpRequestBase request) {
return IsMobileInternal(request.UserAgent) && !IsForcedDesktop(request);
}
public static bool IsTablet(this HttpRequestBase request) {
return IsTabletInternal(request.UserAgent) && !IsForcedDesktop(request);
}
public static void OverrideBrowser(this HttpRequestBase request, bool forceDesktop){
request.RequestContext.HttpContext.Cache[OVERRIDE_BROWSER_CACHE_KEY] = forceDesktop;
}
public static bool IsForcedDesktop(this HttpRequestBase request){
var isForced = request.RequestContext.HttpContext.Cache[OVERRIDE_BROWSER_CACHE_KEY];
return isForced != null ? isForced.ToString().ToBool() : false;
}
private static bool IsMobileInternal(string userAgent) {
var device = WURFLManagerBuilder.Instance.GetDeviceForRequest(userAgent);
if (device.IsTablet() == true) {
return false;
} else {
return device.IsMobile();
}
}
private static bool IsTabletInternal(string userAgent) {
var device = WURFLManagerBuilder.Instance.GetDeviceForRequest(userAgent);
return device.IsTablet();
}
It all works fine for a while, but then after an hour or so, mobile and tablet devices start displaying the desktop views, and the desktop view starts showing the ViewSwitcher shared view (I assume most people are familiar with it, it just allows you to show the desktop view from a mobile device). It's almost like that caching bug in mvc4. I have tried removing my code to register the display modes, and just went with the default mvc mobile support, and it works fine it has the same issue! So clearly there's a problem in here somewhere... can anyone see anything obvious? Almost impossible to debug cause problems only start coming up after a long time, and even then only on the live system really! Any ideas?
Thanks heaps... been on this issue for way too long now...
Cheers
Andy
EDIT: even stripping it right back to the default implementations creates the issue. I added some debugging code to make sure I'm actually running mvc5, but it appears I am. I've also tried the initially recommended workaround for the issue on mvc4 by disabling the cache, still no joy. Is there really no one with info on this?
So I finally figured it out. Very simple as usual. For some reason I used RequestContext.HttpContext.Cache to save the status when someone wants the full view as opposed to the mobile view. I've never used HttpContext.Cache, I'm pretty sure I would have taken that from a blog somewhere - can't find it anymore though. So all that happened was that it would switch the view for everyone, not just the one person. Can't believe it took weeks to figure that out. Hope it helps someone else at some point.

Remove a ScreenSpaceLines3D Object from a ViewPort?

I am making a 3D Game with WPF in VB, and I am using a ScrennSpaceLines3D Object I found
http://3dtools.codeplex.com/releases/view/2058
but when I try to remove a line I added to the viewport by using
mainViewport.Children.RemoveAt(i)
it gives a NullExceptionError. I have read that this is because it does not totally come off the rendering queue. There have been fixes for c#, but I have yet to find one that works with VB. Is there a way to make this work or possibly draw a line in 3D space some other way? I find it quite ridiculous that VB doesn't even have a way to easily draw 3D lines...
Remove ScreenSpaceLines3D :
foreach (ScreenSpaceLines3D line3D in lines3DList)
{
lines3D.Points.Clear(); // Very importante
_viewport3D.Children.Remove(lines3D);
}
I'm a bit late to the party but i'm having the same issues.
The access violation occurs because each instance registers an event handler to the Rendering event of the composition target
public ScreenSpaceLines3D()
{
...
CompositionTarget.Rendering += OnRender; // <-- this line
}
but forgets to remove it when the instance is removed from the scene.
So to fix this you need to touch the source code:
public ScreenSpaceLines3D()
{
...
// event registration removed
}
private bool AttachedToCompositionTargetRendering { get; set; }
protected override void OnVisualParentChanged(DependencyObject oldParent)
{
base.OnVisualParentChanged(oldParent);
var parent = VisualTreeHelper.GetParent(this);
if (parent == null)
{
if (AttachedToCompositionTargetRendering)
{
CompositionTarget.Rendering -= OnRender;
AttachedToCompositionTargetRendering = false;
}
}
else
{
if (!AttachedToCompositionTargetRendering)
{
CompositionTarget.Rendering += OnRender;
AttachedToCompositionTargetRendering = true;
}
}
}

Advisable to touch the codes in Designer.cs file?

Is it advisable for me to touch the designer.cs file for my windows form application? As I am referencing the labels to my settings file, I plan to code it in such a way that if my settings file shows
int startup = 0;
the code handler for my combo box selection would be
if (settingObject.bootOnStartup == 0)
{
comboStartup.SelectedIndex = 0;
}
else
{
comboStartup.SelectedIndex = 1;
}
it does works for its function but it sort of crashes the design window.
Don't modify the .designer.cs files, ever. Whatever you do in it, it will be overwritten the next time you edit your Form in the designer, so you will have to do it again. I don't see any reason not to put this code in the Form constructor or the Load event...
Your last sentence is the answer. If anything needs special treatment, do it in the user part of the partial class. Even if in your case (I'm speculating) this would require creating a ComboBox manually before the designer code runs.
The only time I touch the designer code is when I simply and quickly want to change something that I'm sure will survive the code generation of VS, e.g. a property name in a binding.
The Designer.cs file tells you not to modify:
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent( ) {
/* ...control customization from designer... */
}
If you have modifications then make those in your Form constructor after InitializeComponent:
public MainForm( ) {
InitializeComponent( );
if (settingObject.bootOnStartup == 0) {
comboStartup.SelectedIndex = 0;
} else {
comboStartup.SelectedIndex = 1;
}
}
... or, on a this.Load event:
public MainForm( ) {
InitializeComponent( );
this.Load += (s, e) => {
if (settingObject.bootOnStartup == 0) {
comboStartup.SelectedIndex = 0;
} else {
comboStartup.SelectedIndex = 1;
}
};
}

WPF WebBrowser control zoom in/out support?

For a WPF WebBrowser control, is there a way to duplicate Internet Explorer's zoom functionality?
In other words, Internet Explorer has the menu View > Zoom > 75%, which renders the web page at 75% scale. Is there a way to make a web browser control, which is embedded in a WPF app, do the same thing?
I've seen this post:
WPF WebBrowser - How to Zoom Content?
But it only seems to scale the page and not the page content.
public partial class TestWindow: UserControl
{
public TestWindow()
{
InitializeComponent();
browser.LoadCompleted += new LoadCompletedEventHandler(browser_LoadCompleted);
}
private void browser_LoadCompleted(object sender, NavigationEventArgs e)
{
try
{
FieldInfo webBrowserInfo = browser.GetType().GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
object comWebBrowser = null;
object zoomPercent = 120;
if (webBrowserInfo != null)
comWebBrowser = webBrowserInfo.GetValue(browser);
if (comWebBrowser != null)
{
InternetExplorer ie = (InternetExplorer)comWebBrowser;
ie.ExecWB(SHDocVw.OLECMDID.OLECMDID_OPTICAL_ZOOM, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, ref zoomPercent, IntPtr.Zero);
}
}
catch (Exception ex)
{
}
}
public void SetBrowser(string url)
{
browser.Navigate(url,null,null,null);
}
internal void Destroy()
{
try
{
if (browser.Parent != null)
{
((Grid)browser.Parent).Children.Remove(browser);
browser.Navigate("about:blank");
browser.Dispose();
browser = null;
}
}
catch { }
}
}
Here's how I did it:
// Needed to expose the WebBrowser's underlying ActiveX control for zoom functionality
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
internal interface IServiceProvider
{
[return: MarshalAs(UnmanagedType.IUnknown)]
object QueryService(ref Guid guidService, ref Guid riid);
}
static readonly Guid SID_SWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
private void ZoomListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
object zoomPercent; // A VT_I4 percentage ranging from 10% to 1000%
switch(ZoomListBox.SelectedItem.ToString())
{
case "System.Windows.Controls.ListBoxItem: 200%":
zoomPercent = 200;
break;
case "System.Windows.Controls.ListBoxItem: 100%":
zoomPercent = 100;
break;
case "System.Windows.Controls.ListBoxItem: 50%":
zoomPercent = 50;
break;
default:
zoomPercent = 100;
break;
}
// grab a handle to the underlying ActiveX object
IServiceProvider serviceProvider = null;
if (m_webView.Document != null)
{
serviceProvider = (IServiceProvider)m_webView.Document;
}
Guid serviceGuid = SID_SWebBrowserApp;
Guid iid = typeof(SHDocVw.IWebBrowser2).GUID;
SHDocVw.IWebBrowser2 browserInst = (SHDocVw.IWebBrowser2)serviceProvider.QueryService(ref serviceGuid, ref iid);
// send the zoom command to the ActiveX object
browserInst.ExecWB(SHDocVw.OLECMDID.OLECMDID_OPTICAL_ZOOM, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, ref zoomPercent, IntPtr.Zero);
}
All the service provider stuff exposes the ActiveX since the WPF WebBrowser control doesn't expose it directly. Aside from that, it's pretty much the same as alexei's solution.
This is not an exact answer since it is for the WinForms control, but perhaps will be useful in case you decide to use it in a WindowsFormsHost instead of the WPF control, which exposes way too little to be useful.
You could use an OLE commands through ExecWB on the ActiveX instance: OLECMDID_ZOOM for text size and OLECMDID_OPTICAL_ZOOM for optical zoom. For example,
object pvaIn = 200; // A VT_I4 percentage ranging from 10% to 1000%
var browserInst = ((SHDocVw.IWebBrowser2)(browserContol.ActiveXInstance));
browserInst.ExecWB(SHDocVw.OLECMDID.OLECMDID_OPTICAL_ZOOM,
SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER,
ref pvaIn, IntPtr.Zero);
Some notes:
a reference to Interop.SHDocVw assembly is needed
the command succeeds only after a document has loaded
the range of pvaIn could be retrieved via OLECMDID_GETZOOMRANGE
for reference list of commands is on MSDN
I experienced this strange behavior that seemed to happen only on non-96 dpi. Upon startup, the rendered text size did not correspond to that stored in OLECMDID_ZOOM state. Setting the value (to any value) did not fix the discrepancy: the rendered size is still what looked like [stored size + 2]. When optical zoom was set to 100%, the discrepancy in text-size went away (text size visibly shrank after zooming to 100%). This did't happen in IE, and perhaps that was just a weird artifact in my environment -- but just fyi.
When using the other solutions, I always get errors of kind
HRESULT: 0x80040100
DRAGDROP_E_NOTREGISTERED
I found a solution on this page that worked for me:
var wb = webBrowser.ActiveXInstance.GetType();
object o = zoomPercentage; // Between 10 and 1000.
wb.InvokeMember(
#"ExecWB",
BindingFlags.InvokeMethod,
null,
webBrowser.ActiveXInstance,
new[]
{
OLECMDID.OLECMDID_OPTICAL_ZOOM,
OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER,
o,
o
});
With OLECMDID_OPTICAL_ZOOM being 63 and OLECMDEXECOPT_DONTPROMPTUSER being 2.

Silverlight 4: Detect browser F5 / refresh and X / Close

I want to determine how to filter F5, refresh button, X and close in browser via silverlight 4.0 or even in server side.
thank you
EDITED:
I added bounty to my question just today, July 28 2011. My previous solution / answer is no longer working in IE 9.
window.onunload = function (e) {
// Firefox || IE
e = e || window.event;
var y = e.pageY || e.clientY;
if (y < 0) {
alert("close");
}
else {
alert("refresh");
}
}
When the user hit F5, refresh, X and close button, message box should NOT appear. Just in case the solution is onbeforeunload.
Thanks for you help!
It is not possible client-side to determine whether an application startup is the result of a refresh operation performed by the user.
However you can determine at serverside that a page is being refreshed. You can add the following property to the code-behind of the ASPX page hosting the Silverlight application.
public bool IsRefresh
{
get { Request.Headers["pragma"] ?? "").Contains("no-cache"); }
}
Now you use this property to conditionally include a value in the silverlight plugin initParams.
<object ...>
<param name="initParams" value="IsRefresh=<%=IsRefresh.ToString()%>" />
</object>
Then in silverlight code you can determine if the application was last loaded as a result of a refresh with:-
if (Application.Current.Host.InitParams["IsRefresh"] == "True")
since it is not possible in client side, i did it in server side.
I solve my problem using this code:
window.onunload = function (e) {
// Firefox || IE
e = e || window.event;
var y = e.pageY || e.clientY;
if (y < 0) {
alert("close");
}
else {
alert("refresh");
}
}
There is no property to check if your application is loaded by pressing the F5-button but you could handle the application startup event and set a variable with a datetime. The moment your page gets loaded you can check if the timespan is just a couple of seconds ago. So now you know that the application is loaded the first time or the F5-button is pressed when that time it is only a couple of seconds ago.
I don't know if this is sufficient for you but you can give it a try:
App.xaml.cs
public class App : Application
{
private DateTime appStartupTime {get; set};
public App()
{
Startup += new EventHandler(Application_Startup);
}
void Application_Startup(object sender, StartupEventArgs e)
{
//initialize the startupTime
appStartupTime = DateTime.Now;
}
public bool IsApplicationReLoaded
{
get
{
//return true if your app is started less 10 seconds ago
return DateTime.Now.AddSeconds(-10) < appStartupTime;
}
}
}
Now you can start using the code below from everywhere
(Application.Current as App).IsApplicationReloaded

Resources