CefSharp SetZoomLevel not working - vb.net

I am using in a WinForm an object of type:
CefSharp.WinForms.ChromiumWebBrowser
Everything is working fine but I am having an issue when I try to change the ZoomLevel with SetZoomLevel method:
If oBrowser.IsBrowserInitialized Then
oBrowser.SetZoomLevel(-2.0)
Dim frame As CefSharp.IFrame = oBrowser.GetMainFrame
Dim request As CefSharp.IRequest = frame.CreateRequest()
request.Url = url
request.Method = "POST"
request.InitializePostData()
Dim element = request.PostData.CreatePostDataElement()
element.Bytes = postDataBytes
request.PostData.AddElement(element)
request.Headers = headers
frame.LoadRequest(request)
End If
The first time I open the WinForm the Zoom level doesn't change, while it works correctly from the 2nd refresh.
Am I missing some initialization and/or method call... Or do I have to call this method in another position?
Note: the CEFSharp DLL version is 63.0.3.0.
The .NET Framework is 4.5.2
EDITED 01.06.2018: I've found a solution (see below) but now there's another problem: the zoom change is made when the browser is already visible, so it's not nice for the final user to see the page size changing during the form load.
Has anyone a suggestion to freeze the layout during zoom change? Please note that .SuspendLayout() and .ResumeLayout() are not working.

I've found a way to answer my own question. I post it here as it could be useful to other users.
You must add a LoadingStateChanged handler to the ChromiumWebBrowser object:
AddHandler oBrowser.LoadingStateChanged, AddressOf WebBrowserOnLoadingStateChanged
The method would be then something like:
Private Sub WebBrowserOnLoadingStateChanged(ByVal sender As Object, ByVal loadingStateChangedEventArgs As LoadingStateChangedEventArgs)
Dim oBrowser As WinForms.ChromiumWebBrowser = CType(sender, WinForms.ChromiumWebBrowser)
If Not oBrowser.IsLoading Then
oBrowser.SetZoomLevel(-2.0)
End If
End Sub
This solution works good in my environment but now there's another problem: the zoom change is made when the browser is already visible, so it's not nice for the final user to see the Zoom Level changing during the form load.

Related

Looking for a specific tag

I had a previous question regarding a way to access a proxy card from within a web page when using Chrome. I'm now attempting to instead use a vb.Net application with an embedded CefSharp object. I have the code I need to access the proxy card (thanks to Smart Card API), but I need an easy way to indicate that this is even an option. My thought is to:
Put an otherwise empty element on the web page (such as <div id='smartcard' />)
Inside Visual Basic, monitor the contents of the page for this <div />
If the <div /> is found, make sure the card reader is detected. If so, add some text (and maybe an image) to its contents indicating the the card can be scanned
Once a card scan is detected, put the value from the card into a form element and POST it
It seems likely to me that I'm going to have to use some combination of JavaScript and vb.net code, but I'm so new to CefSharp that I really have no idea where to start.
Thanks in advance for all your help.
Not being a C# programmer, I looked at the information on the General Usage guide many times and still didn't really understand it. That said, I think I've been able to get this project off the ground. In addition to the CefSharp project, I'm also using the non-free Smart Card API from CardWerk.
Below is some snippets of what I did.
VB.Net
Imports CefSharp
Imports Subsembly ' For the SmartCard namespace
Class MainWindow
Private WithEvents CardManager As SmartCard.CardTerminalManager
Private Sub MainWindow_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
browser.Address = "https://jake-dev7.local/trainingmatrix/"
Debug.Print(SmartCard.SMARTCARDAPI.API_VERSION)
CardManager = SmartCard.CardTerminalManager.Singleton
CardManager.Startup(True)
End Sub
Private Sub browser_LoadingStateChanged(sender As Object, e As LoadingStateChangedEventArgs) Handles browser.LoadingStateChanged
Dim script As String
If Not e.IsLoading Then
If CardManager.SlotCount Then
script = "if ($('#proxcard').length) { proxcard_init() }"
browser.GetMainFrame().ExecuteJavaScriptAsync(script)
End If
End If
End Sub
Protected Sub InsertedEvent(ByVal aSender As Object, ByVal aEventArgs As SmartCard.CardTerminalEventArgs) Handles CardManager.CardInsertedEvent
Dim aCard As SmartCard.CardHandle
Dim nActivationResult As SmartCard.CardActivationResult
Dim iFacilityCode As Integer
Dim iCardID As Integer
' There's a bunch of code here taken from the sample code that came
' with the SmartCard API from CardWerk to pull the facility code and
' card id out of the prox card.
If iFacilityCode <> 0 And iCardID <> 0 Then
Dim script As String
script = "if ($('#proxcard').length) { proxcard_scan(" & iFacilityCode & ", " & iCardID & ") }"
browser.GetMainFrame().ExecuteJavaScriptAsync(script)
End If
End Sub
End Class
JavaScript
(This is in a .js file that is loaded by the web page. This page can also be loaded in Chrome, Firefox, IE, etc and these functions will never be run which keeps this utility usable for computers that don't have the custom .exe and card reader).
// These proxcard_* functions are called via our parent application
// (CefSharp object embeded in a vb.Net assembly)
function proxcard_init() {
$('#proxcard').html("<div class='or'>- OR -</div><div><img src='proxcard.jpg'><br>Scan your card</div>");
}
function proxcard_scan(facilityID, cardID) {
var vars = {
facilityID: facilityID,
cardID: cardID
};
if ($('form#adduser').length) {
// We're on the add user page. Check to see if this card matches somebody.
$.post('httprequest.php?type=get-emp-from-prox', vars, function(data) {
if (data && data.number) {
// Update UI and backend form fields. If everything validates, submit the form
} else {
// Clear UI and backend form fields that pertain to user ID
alert('Card not found');
}
}, 'json');
} else if ($('form#update').length) {
// Deal with the update form
}
}
In my actual code, I have multiple else if statements for dealing with different forms where I allow a card to be scanned. They are not included to keep this from getting out of hand :).
Please Note: This is not intended to be the entire project or all the code needed to process prox cards using CefSharp. My hope is that it will be enough to help somebody else.

Image array help in Silverlight

I'm Back! And having more Silverlight issues (yay!)
I am trying to create an image array in Silverlight but the images are not appearing on the page. Here is my code:
Public imgImages(50) As Image
Public Sub Create_Image_Array()
Dim I As Integer
For I = 0 To 50
imgImages(I) = New Image
imgImages(I).SetValue(Canvas.LeftProperty, System.Convert.ToDouble(0))
imgImages(I).SetValue(Canvas.TopProperty, System.Convert.ToDouble(0))
imgImages(I).Name = "imgImages" & I
imgImages(I).Width = System.Convert.ToDouble(18)
imgImages(I).Height = System.Convert.ToDouble(18)
imgImages(I).Source = New BitmapImage(New Uri("/Resources/yellow2.png", UriKind.Relative))
imgImages(I).Visibility = Windows.Visibility.Visible
AddHandler imgImages(I).MouseLeftButtonUp, AddressOf ImageClickEventProc
Next I
End Sub
Public Sub Draw_Images()
For I = 1 To secObject.intNumberOfImages
imgImages(I).SetValue(Canvas.LeftProperty, System.Convert.ToDouble(secObject.Images(I).intPosX))
imgImages(I).SetValue(Canvas.TopProperty, System.Convert.ToDouble(secObject.Images(I).intPosY))
imgImages(I).Visibility = Windows.Visibility.Visible
Next I
End Sub
The image array is created when the page is navigated to and then the page requests location information from a server and once it has that information it sets the X and Y coordinates of the images. All that part works fine - that was apparently the easy part - All the coordinate information is received and stored in secObject, the data is there. The URI for the resource of the image is there and it is valid, I tested it with another image control on the page.
The problem is that the little images are not displaying. I have tried numerous ways of getting them to display. I have found code on Google that does almost the exact same thing that I am trying to do and it is written in a similar way just for non-arrayed images.
I also tried another suggestion, to use TranslateTransform to set the positions of the images. This did nothing.
Dim tt As New TranslateTransform
tt.X = secObject.Images(I).intPosX
tt.Y = secObject.Images(I).intPosY
imgImages(I).RenderTransform = tt
I also removed the background image on the screen thinking that maybe the images were rendering below the background, and that is not the case.
Am I missing something? I admit to being a Silverlight n00b...
Thanks
-RW
OK I finally figured it out... I needed to create add the controls to the canvas:
LayoutRoot.Children.Add(imgImages(I))

Proxy change on runtime in Awesomium

I've read bunch of Q&As but none helped me.
I'm using VB.net; added awesomium browser control on the form. I need to be able to change its proxy server on the fly (example: User clicks a button to change proxy IP & port). Would it be possible? If not maybe I could create a dynamic awesomium browser control and than add it to the form (also on button click). But still don't know how to initialize control with the proxy.
If I cannot change it while running that is fine. Can I read proxy from some file and than initialize control with that proxy?
Nevermind - below worked for me:
Dim prefs As WebPreferences = New WebPreferences()
prefs.ProxyConfig = txtProxy.Text
Dim session As WebSession = WebCore.CreateWebSession(prefs)
Dim webcontrol As WebControl = New WebControl()
webcontrol.WebSession = session
Me.panWeb.Controls.Add(webcontrol)
webcontrol.Dock = DockStyle.Fill
webcontrol.Source = New Uri(txtURL.Text)
webcontrol.Visible = True

Windows Store App Search Contract Blank Screen

I recently added the search contract to my app. It is working great! But, whenever I search in the app when it is not running, it only starts with a blank screen. I did the part to add search results even in OnSearchActivated method. But even if I remove the code that I added, the blank screen persists. I created a blank project and added the search contract to it. And it is working in it even when the app is not running. The issue seems to be with my app only. I cannot debug it because it is something that runs when the app is not even running. Tell me a solution.
Code in OnSearchActivated and OnLaunched
Protected Overrides Async Sub OnSearchActivated(args As Windows.ApplicationModel.Activation.SearchActivatedEventArgs)
Dim previousContent As UIElement = Window.Current.Content
Dim frame As Frame = TryCast(previousContent, Frame)
If frame Is Nothing Then
frame = New Frame
Common.SuspensionManager.RegisterFrame(frame, "AppFrame")
If args.PreviousExecutionState = ApplicationExecutionState.Terminated Then
Try
Await Common.SuspensionManager.RestoreAsync()
Catch ex As Common.SuspensionManagerException
End Try
End If
End If
frame.Navigate(GetType(SearchResultsPage1), args.QueryText)
Window.Current.Content = frame
Window.Current.Activate()
End Sub
Protected Overrides Async Sub OnLaunched(args As Windows.ApplicationModel.Activation.LaunchActivatedEventArgs)
AddHandler SearchPane.GetForCurrentView.SuggestionsRequested, AddressOf OnSearchPaneSuggestionsRequested
'Contains definition of arrays ExNam, ExAbbr, ExInst, etc. removed from here to shorten the code and focus on its logic
If rootFrame Is Nothing Then
rootFrame = New Frame()
Train_Thy_Brain.Common.SuspensionManager.RegisterFrame(rootFrame, "appFrame")
If args.PreviousExecutionState = ApplicationExecutionState.Terminated Then
Await Train_Thy_Brain.Common.SuspensionManager.RestoreAsync()
End If
Window.Current.Content = rootFrame
End If
If rootFrame.Content Is Nothing Then
If Not rootFrame.Navigate(GetType(Instructions), args.Arguments) Then
Throw New Exception("Failed to create initial page")
End If
End If
Window.Current.Activate()
End Sub
'Also the namespace definitions are done at the top so they are not the issues neither.
There is a solution to debug your app : in VS2012, Right-click on your project in the Solution Explorer, then go to the Debug tab and in the Start Action section, check "Do not launch, but debug my code when it starts".
Now you can start your app from the Search Contract even if it is not running yet and debug it!
Now for your problem, I would suggest you to check whether the data is loaded before you actually search for something.
You might be hitting the search activation with empty query string. Check your search activation handler, whether you are handling the blank query text case or not?
protected override void OnSearchActivated(SearchActivatedEventArgs args)
{
// your app initialization code here.
Frame frame = (Frame)Window.Current.Content;
if (!string.IsNullOrEmpty(args.QueryText))
{
frame.Navigate(typeof(SearchResultsPage), args.QueryText);
}
else
{
// navigate to your app home page if the query text is empty.
frame.Navigate(typeof(Home), null);
}
Window.Current.Activate();
}

Modify HTML in a Internet Explorer window using external.menuArguments

I've got a VB.NET class that is invoked with a context menu extension in Internet Explorer.
The code has access to the object model of the page, and reading data is not a problem. This is the code of a test function...it changes the status bar text (OK), prints the page HTML (OK), changes the HTML by adding a text and prints again the page HTML (OK, in the second pop-up my added text is in the HTML)
But the Internet Explorer window doesn't show it. Where am I doing wrong?
Public Sub CallingTest(ByRef Source As Object)
Dim D As mshtml.HTMLDocument = Source.document
Source.status = "Working..."
Dim H As String = D.documentElement.innerHTML()
MsgBox(H)
D.documentElement.insertAdjacentText("beforeEnd", "ThisIsATest")
H = D.documentElement.outerHTML()
MsgBox(H)
Source.status = ""
End Sub
The function is called like this from JavaScript:
<script>
var EB = new ActiveXObject("MyObject.MyClass");
EB.CallingTest(external.menuArguments);
</script>
To the best of my understanding, in order to use insertAdjacentText or any of the other editing methods, the document object should be in the design mode.
In design mode you can edit the document freely, and so can the user.
Check this site for more details
I do not think that Alex is right, something else is the matter.
When I tried to do something like that, insertBefore would not work for me, but appendChild worked just fine, so adding an element is possible.
I worked in Javascript, but I don't expect that makes a difference.