How to use CKEditor 5 Image upload? - vb.net

Hi I am currently using CKEditor 5 and my problem is the image upload. The ckeditor allows me to upload an image and it displays within the CKEditor, the file is also being uploaded to a folder using a custom VB Script but i keep getting the error: Cannot upload file - filename. Then the Image disappears from ckeditor. Does anyone know what i am doing wrong? is the image URL not being passed back properly to CKEditor?
var myEditor;
ClassicEditor
.create(document.querySelector('#CKEditor1'), {
ckfinder: {
filebrowserUploadMethod: 'form',
// Upload the images to the server using the CKFinder QuickUpload command.
uploadUrl: 'Scripts/uploadVB.aspx?CKEditor=CKEditor1&CKEditorFuncNum=1&langCode=en'
}
})
.then(editor => {
console.log('Editor was initialized', editor);
myEditor = editor;
})
.catch( error => {
console.error( error );
});
<div id="CKEditor1">This is some sample content.</div>
UploadVB Page
<%# Page Language="VB" Strict="true"%>
<script src="https://cdn.ckeditor.com/ckeditor5/22.0.0/classic/ckeditor.js"></script>
<script runat="server">
Sub Page_Load(ByVal o As Object, ByVal e As EventArgs)
Response.Write(processUpload())
'processUpload()
End Sub
'https://github.com/AlfonsoML/CKEditorUploader/blob/master/uploadVB.aspx
Dim basePath As String = "C:\Users\new\Image\CN_Image"
' Step 3: Put here the Url that should be used for the upload folder (it the URL to access the folder that you have set in $basePath
' you can use a relative url "/images/", or a path including the host "http://example.com/images/"
' ALWAYS put the final slash (/)
Dim baseUrl As String = "/Image/CN_Image/"
' Done. Now test it!
' No need to modify anything below this line
'----------------------------------------------------
' ------------------------
' Input parameters: optional means that you can ignore it, and required means that you
' must use it to provide the data back to CKEditor.
' ------------------------
' Optional: instance name (might be used to adjust the server folders for example)
Dim CKEditor As String = HttpContext.Current.Request("CKEditor")
' Required: Function number as indicated by CKEditor.
Dim funcNum As String = HttpContext.Current.Request("CKEditorFuncNum")
'Dim CKEditorFuncNum As String = Context.Request("CKEditorFuncNum")
' Optional: To provide localized messages
Dim langCode As String = HttpContext.Current.Request("langCode")
' ------------------------
' Data processing
' ------------------------
Dim total As Integer
Try
total = HttpContext.Current.Request.Files.Count
Catch ex As Exception
Return sendError("Error uploading the file")
End Try
If (total = 0) Then
Return sendError("No file has been sent")
End If
If (Not System.IO.Directory.Exists(basePath)) Then
Return sendError("basePath folder doesn't exists")
End If
'Grab the file name from its fully qualified path at client
Dim theFile As HttpPostedFile = HttpContext.Current.Request.Files(0)
Dim strFileName As String = theFile.FileName
If (strFileName = "") Then
Return sendError("File name is empty")
End If
Dim sFileName As String = System.IO.Path.GetFileName(strFileName)
Dim name As String = System.IO.Path.Combine(basePath, sFileName)
theFile.SaveAs(name)
Dim url As String = baseUrl + sFileName.Replace("'", "\'")
' ------------------------
' Write output
' ------------------------
Return "<scr" + "ipt type='text/javascript'> window.parent.CKEDITOR.tools.callFunction(" + funcNum + ", '" + url + "', '')</scr" + "ipt>"
End Function
Private Function sendError(ByVal msg As String) As String
Dim funcNum As String = HttpContext.Current.Request("CKEditorFuncNum")
Return "<scr" + "ipt type='text/javascript'> window.parent.CKEDITOR.tools.callFunction(" + funcNum + ", '', '" + msg + "')</scr" + "ipt>"
End Function
</script>

Related

Upload a file to SharePoint using REST API and vb.net

I have a project to upload files to Sharepoint using REST API ( POST).
I am using vb.net and RestSharp. Code is below. this code is working.
I am able to do with the small Text file only and the file is getting properly upload into Sharepoint. But when it comes to another file format ( XLS, XLSX, PDF, JOG, Doc ..etc) with a file size greater than 1 MB file is getting uploaded with it, not in a readable format. I tried to upload a ZIP file for 55 MB it is getting Uploaded. But When I download the same uploaded file I am not able to read it.
Can anyone please help me, to get this fixed?
** I would need a solution to upload any file format for any size ( In my project I will not use any file more than 500 MB for upload. )
Below is the code is tried.
Public Sub UploadFile2()
Dim FullfileName As String = "E:\Desktop\try\FileToUpload.xlsx"
Dim NewFileName As String = "NewFile.xlsx"
Dim uploadFileUrl As String = SiteUrl + "_api/web/lists/getByTitle('Documents')/RootFolder/Files/Add(url='" + NewFileName + "', overwrite=true)"
Dim client = New RestClient(uploadFileUrl) With {
.Timeout = -1
}
Dim UploadRequest = New RestRequest(Method.POST)
UploadRequest.AddHeader("Accept", "application/json;odata=verbose")
UploadRequest.AddHeader("X-RequestDigest", DigestValue)
UploadRequest.AddHeader("Authorization", "Bearer " + AccessToken)
UploadRequest.AddHeader("Content-Type", "multipart/form-data")
UploadRequest.AlwaysMultipartFormData = True
UploadRequest.AddFile("FileName", FullfileName)
UploadResponse = client.Execute(UploadRequest)
End Sub
Looks like you need to pass the Content-Length header.
For anyone interested, this worked for me:
Public Sub UploadFile2()
Dim FullfileName As String = "E:\Desktop\try\FileToUpload.xlsx"
Dim NewFileName As String = "NewFile.xlsx"
Dim uploadFileUrl As String = SiteUrl + "_api/web/lists/getByTitle('Documents')/RootFolder/Files/Add(url='" + NewFileName + "', overwrite=true)"
Dim client = New RestClient(uploadFileUrl) With {
.Timeout = -1
}
Dim UploadRequest = New RestRequest(Method.POST)
UploadRequest.AddHeader("Accept", "application/json;odata=verbose")
UploadRequest.AddHeader("X-RequestDigest", DigestValue)
UploadRequest.AddHeader("Authorization", "Bearer " + AccessToken)
UploadRequest.AddHeader("Content-Type", "application/octet-stream")
UploadRequest.AddParameter("application/octet-stream", File.ReadAllBytes(FullfileName), ParameterType.RequestBody)
UploadResponse = client.Execute(UploadRequest)
End Sub

Random assembly / application name everytime the applicaiton is launched VB.NET code

I have been trying to figure out a way to make it so everytime i launch my application it renames the application to a random string.
My application is in VB.NET
This is my frmLogin.vb (i put the code inside same class as login, since login is my start window, didnt know where else to put it)
Code:
Private Shared Sub Main(ByVal args As String())
Const REGISTRY_KEY As String = "HKEY_CURRENT_USER\Prototype"
Const REGISTY_FIRSTRUN As String = "FirstRun"
Const REGISTY_LASTNAME As String = "LastName"
Dim RandomTitle As String = RandomString(RandomShit.[Next](5, 15)) & ".exe"
Try
If Convert.ToInt32(Microsoft.Win32.Registry.GetValue(REGISTRY_KEY, REGISTY_FIRSTRUN, 0)) = 0 Then
Console.Title = RandomTitle
Dim TempPath As String = Convert.ToString(Microsoft.Win32.Registry.GetValue(REGISTRY_KEY, REGISTY_LASTNAME, 0))
If AppDomain.CurrentDomain.FriendlyName <> "RandomShit.exe" Then
File.Delete("RandomShit.exe")
End If
If File.Exists(TempPath) Then
File.Delete(TempPath)
End If
Microsoft.Win32.Registry.SetValue(REGISTRY_KEY, REGISTY_FIRSTRUN, 1, Microsoft.Win32.RegistryValueKind.DWord)
Microsoft.Win32.Registry.SetValue(REGISTRY_KEY, REGISTY_LASTNAME, Directory.GetCurrentDirectory() & "\" + AppDomain.CurrentDomain.FriendlyName, Microsoft.Win32.RegistryValueKind.String)
End If
Finally
End Try
End Sub
I am not sure whether below code completely satisfied your requirement. I hope below works for you to rename an executable file:
File.Move(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName, Path.Combine(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName), "randomstring.exe"))

io.file.Readalllines works for one file name but not for anyothers also does not throw exception on invalid filename

The files I am trying to read are in a file called systemstate in the bin\debug file. I have a text file call systemdetails in that file and a file in there called Products and a file of products called P0 containing the rest of the text files
in the following lines of code the first readalllines works, the rest fails without any exception raised and the program continues to run as if nothing happened.
in the form1.vb file
Public Sub init()
If start Then
productcount = Int(IO.File.ReadAllLines(filestoreloc + systemfile)(0).Split()(1))
For i As Integer = 0 To productcount
Dim id As String = Str(i)
Dim det As String() = IO.File.ReadAllLines(filestoreloc + Product.location + "P" + id + Product.detailsfile)
Dim desc As String() = IO.File.ReadAllLines(filestoreloc + Product.location + "P" + id + Product.descriptionfile)
Dim rev As String() = IO.File.ReadAllLines(filestoreloc + Product.location + "P" + id + Product.reviewfile)
products.Add(New Product(det, desc, extractRecords(rev, Product.revstartmark, Product.revendmark)))
Next
start = False
End If
End Sub
This method is invoked from the Form1_load method
these are the variables used in the above code:
in the form1.vb file
Property filestoreloc As String = "systemstate\"
Property systemfile As String = "systemdetails.txt"
Property productcount As Integer
Property start As Boolean = True
in the product.vb file
Public Shared Property location As String = "Products\"
Public Shared Property detailsfile As String = "\details.txt"
Public Shared Property descriptionfile As String = "\description.txt"
Public Shared Property reviewfile As String = "\reviews.txt"
Public Shared Property revstartmark As String = "[REVIEWSTART]"
Public Shared Property revendmark As String = "[REVIEWEND]"
an exception was not showing up. this exception was because the directory couldn't be found because when I converted the id to a string there was a leading space #StevenDoggart helped me detect the exception

Checking with VB.net if File exists in dropbox folder

Here is my code.
Yes, I am using both, DropNet and Dropbox APIs as I found the DropNet upload works nicely. But I am trying to use the Dropbox one to check for filename (as I couldn't get it to work on DropNet and could not find any help about it online)
I have little doubt that my problem has something to do with the whole Async & Await , as I have never worked with this stuff before.
The File Upload & Get Share both work just fine.
This is a VB.Net Website.
When I run it, it freezes in side the DoesDropBoxFileExist function
Imports Dropbox.Api
Imports DropNet
Imports DropNet.Models
Partial Class _Default
Inherits System.Web.UI.Page
Dim br As String = "<br>"
Public FileName As String
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If FileUpload1.HasFile Then
Dim dropNet_client As New DropNetClient("", "", "")
Dim dropBox_client As New DropboxClient("")
FileName = FileUpload1.PostedFile.FileName
Response.Write("before: " & FileName & br)
MsgBox(1)
FileName = DoesDropBoxFileExist(dropBox_client).Result
MsgBox(3)
Response.Write("after: " & FileName & br)
Dim content As Byte() = FileUpload1.FileBytes
Dim pathToFile As String = Server.MapPath("~")
'Response.Write(pathToFile)
dropNet_client.UploadFile("/AlertImages/", FileName, content, True)
Dim shareResponse As ShareResponse = dropNet_client.GetShare("/AlertImages/" & FileName)
Response.Write(shareResponse.Url)
If Not FileName.ToLower.Contains("pdf") Then
Dim rawBytes As Byte() = dropNet_client.GetThumbnail("/AlertImages/" & FileName, 2)
Dim base64String As String = Convert.ToBase64String(rawBytes, 0, rawBytes.Length)
Image1.ImageUrl = "data:image/png;base64," & base64String
Image1.Visible = True
End If
dropBox_client.Dispose()
End If
End Sub
Private Async Function DoesDropBoxFileExist(_client As DropboxClient) As Threading.Tasks.Task(Of String)
Dim rtn As String = FileName
Dim list = Await _client.Files.ListFolderAsync("/AlertImages")
MsgBox(2)
' show folders then files
For Each item As Files.Metadata In list.Entries.Where(Function(i) i.IsFolder)
If item.Name = FileName Then
FileName = FileName & Now.ToString
End If
Response.Write(" < b > " & item.Name & "</b>" & br)
'Dim list2 As ListFolderResult = Await dbx.Files.ListFolderAsync(item.Name)
'For Each itm As Files.Metadata In list2.Entries.Where(Function(j) j.IsFile)
' Response.Write(item.Name & " : " & item.AsFile.Size & br)
'Next
Next
For Each item As Files.Metadata In list.Entries.Where(Function(i) i.IsFile)
Response.Write("'" & item.Name & "' '" & FileName & "'" & br)
If item.Name = FileName Then
Response.Write("test" & br)
rtn = FileName & "_" & Now.ToString
End If
Next
Return rtn
End Function
End Class
METHOD 1
To check in VB.NET if a file exists in Dropbox using the API, you can use this method.
First we create a button with a click event as follows:
Private Sub btnCheck_Click(sender As Object, e As EventArgs) Handles btnCheck.Click
'FileToCheck is declared in Form1 as Public Shared
'FileFound is declared in Form1 as Public Shared
FileToCheck = cmbFiles.Text
FileFound = False
Dim task1 = Task.Run(Function() CheckFileMetadata())
task1.Wait()
If FileFound = True Then
'Do something
Else
'Do something else
End If
End Sub
And now the function:
Private Async Function CheckFileMetadata() As Task
Using dbx = New DropboxClient(DbxToken) 'DbxToken = your token text
Try
Await dbx.Files.GetMetadataAsync(Form1.FileToCheck)
FileFound = True
Debug.WriteLine("Found it!")
Catch exapi As ApiException(Of Dropbox.Api.Files.GetMetadataError)
If exapi.ErrorResponse.IsPath And exapi.ErrorResponse.AsPath.Value.IsNotFound Then
Debug.WriteLine("Nothing found at " + Form1.FileToCheck)
End If
Catch ex As Exception
Debug.WriteLine("Error checking file metadata" + vbCrLf + ex.ToString)
End Try
End Using
End Function
This method was adapted from the code here.
METHOD 2
This example demonstrates using VB.NET to recursively iterate through all Dropbox folders to retrieve the names of all files and put them into a collection. Then we check to see if our file is in the collection or not. This method does work, but it's not as efficient as the method above for obvious reasons. I've left it here because it illustrates some additional methods that might help someone.
A couple of notes:
If you have a lot of files and/or folders, there can be a delay due to all of the calls that have to be made to do the recursive processing.
DbxFolders and DbxFiles are declared as Public in the main form class, like so:
Public DbxFolders As New List(Of String)
Public DbxFiles As New List(Of String)
Note use of the .tolower since the Dropbox API returns all found paths in all lowers:
Private Sub btnWalk_Click(sender As Object, e As EventArgs) Handles btnWalk.Click
DbxFolders.Clear()
DbxFiles.Clear()
Dim FindIt As String = "/Folder/File-To-Find.txt".ToLower
Dim task2 = Task.Run(Function() GetTree(String.Empty))
task2.Wait()
If DBFileExists(FindIt) Then MsgBox("Found it!") Else MsgBox("File not found")
End Sub
Private Async Function GetTree(dir As String) As Task
Using dbx = New DropboxClient("Your_Token_Goes_Here")
Dim list = Await dbx.Files.ListFolderAsync(dir)
For Each item In list.Entries.Where(Function(i) i.IsFile)
DbxFiles.Add(item.PathLower)
Next
For Each item In list.Entries.Where(Function(i) i.IsFolder)
DbxFolders.Add(item.PathLower)
Await GetTree(item.PathLower)
Next
End Using
End Function
Private Function DBFileExists(file As String) As Boolean
If DbxFiles.IndexOf(file) > -1 Then Return True Else Return False
End Function
DISCUSSION
Method 1 is obviously the more efficient of the two methods by far because we only call the API once. Note how the ApiException is used in Try-Catch to determine that the file was not found.
Method 2 illustrates some additional concepts that were helpful to me to learn, so I've left it here because someone may have a scenario where this code and the lists that it creates comes in handy.
Note that when we call GetTree(String.Empty), it would be more efficient to pass the specific folder to look in, instead of starting at the root, since we are attempting to match the full path (/path/to/file.txt) in this example anyway, but I wanted to illustrate the recursive iteration because it might be needed in a different situation.
If you don't care what folder an item is in, but only want to see if it exists in a folder without regard to which folder that is, then you would need to use this recursive iteration but instead of item.pathlower you would want to collect item.name instead.
If desired, you can process the collected file list from Method 2 with a simple loop:
For each DbxFile as string in DbxFiles
'Do something
Next

Adding Google Maps to a VB 2010 application

I want to write a Windows Forms application in VB 2010 that will allow the user to search and view addresses or coordinate points on Google Maps. I've already done this by using a WebBrowser item. However I want to use a wrapper so that I can just display the map to the user, but still be able to move and zoom the map or give directions, etc. I know there are ways to do this when developing an ASP.NET site, but I want to do this for a WindowsForms app. Could anyone please help?
Probably too late, but I recently had to deal with google maps in vb and wanted to share my solution:
The first part of this example explains how to implement it. In the second, I will explain how it works. This tries to be a general example. The template for the map (see step 3) and the example functions are fully customizable.
################################# IMPLEMENTATION ############################
Step 1. Firstly, create a new project and select Windows Form Application. Let's leave its name as "Form1".
Step 2. Add a WebBrowser control (which will hold your map) to your Form1. Let's call it "wbmap"
Step 3. Create a .html file named "googlemap_template.html" with your favourite text editor and paste the following code:
googlemap_template.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<style type="text/css">
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#gmap {
height: 100%;
}
</style>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
function initialize() {
//Use window.X instead of var X to make a variable globally available
window.markers = new Array();
window.marker_data = [[MARKER_DATA]];
window.gmap = new google.maps.Map(document.getElementById('gmap'), {
zoom: 15,
center: new google.maps.LatLng(marker_data[0][0], marker_data[0][1]),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var newmarker, i;
for (i = 0; i < marker_data.length; i++) {
if (marker_data[0].length == 2) {
newmarker = new google.maps.Marker({
position: new google.maps.LatLng(marker_data[i][0], marker_data[i][1]),
map: gmap
});
} else if (marker_data[0].length == 3) {
newmarker = new google.maps.Marker({
position: new google.maps.LatLng(marker_data[i][0], marker_data[i][1]),
map: gmap,
title: (marker_data[i][2])
});
} else {
newmarker = new google.maps.Marker({
position: new google.maps.LatLng(marker_data[i][0], marker_data[i][1]),
map: gmap,
title: (marker_data[i][2]),
icon: (marker_data[i][3])
});
}
google.maps.event.addListener(newmarker, 'click', (function (newmarker, i) {
return function () {
if (newmarker.title) {
infowindow.setContent(newmarker.title);
infowindow.open(gmap, newmarker);
}
gmap.setCenter(newmarker.getPosition());
// Calling functions written in the WF
window.external.showVbHelloWorld();
window.external.getMarkerDataFromJavascript(newmarker.title,i);
}
})(newmarker, i));
markers[i] = newmarker;
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<script type="text/javascript">
// Function triggered from the WF with no arguments
function showJavascriptHelloWorld() {
alert("Hello world in HTML from WF");
}
</script>
<script type="text/javascript">
// Function triggered from the WF with a String argument
function focusMarkerFromIdx(idx) {
google.maps.event.trigger(markers[idx], 'click');
}
</script>
</head>
<body>
<div id="gmap"></div>
</body>
</html>
This will serve as our map template. I will explain how it works later.
Step 4. Add the googlemap_template.hmtl file to your project (right click on your project->add->existing item)
Step 5. Once it appears in your Solution Explorer, set its properties to:
- Build Action -> Embedded Resource
- Custom Tool Namespace -> write the
name of the project
Step 6. Add a new class (right click on your project->add->class). In my example I'll call it GoogleMapHelper.
Step 7. Paste the following code into your class:
GoogleMapHelper.vb
Imports System.IO
Imports System.Reflection
Imports System.Text
Public Class GoogleMapHelper
' 1- googlemap_template.html must be copied in the main project folder
' 2- add the file into the Visual Studio Solution Explorer (add existing file)
' 3- set the properties of the file to:
' Build Action -> Embedded Resource
' Custom Tool Namespace -> write the name of the project
Private Const ICON_FOLDER As String = "marker_icons/" 'images must be stored in a folder inside Debug/Release folder
Private Const MAP_TEMPLATE As String = "WindowsApplication1.googlemap_template.html"
Private Const TEXT_TO_REPLACE_MARKER_DATA As String = "[[MARKER_DATA]]"
Private Const TMP_NAME As String = "tmp_map.html"
Private mWebBrowser As WebBrowser
'MARKER POSITIONS
Private mPositions As Double(,) 'lat, lon
' marker data allows different formats to include lat,long and optionally title and icon:
' op1: mMarkerData = New String(N-1, 1) {{lat1, lon1}, {lat2, lon2}, {latN, lonN}}
' op2: mMarkerData = New String(N-1, 2) {{lat1, lon1,'title1'}, {lat2, lon2,'title2'}, {latN, lonN, 'titleN'}}
' op3: mMarkerData = New String(N-1, 3) {{lat1, lon1,'title1','image1.png'}, {lat2, lon2,'title2','image2.png'}, {latN, lonN, 'titleN','imageN.png'}}
Private mMarkerData As String(,) = Nothing
Public Sub New(ByRef wb As WebBrowser, pos As Double(,))
mWebBrowser = wb
mPositions = pos
mMarkerData = getMarkerDataFromPositions(pos)
End Sub
Public Sub New(ByRef wb As WebBrowser, md As String(,))
mWebBrowser = wb
mMarkerData = md
End Sub
Public Sub loadMap()
mWebBrowser.Navigate(getMapTemplate())
End Sub
Private Function getMapTemplate() As String
If mMarkerData Is Nothing Or mMarkerData.GetLength(1) > 4 Then
MessageBox.Show("Marker data has not the proper size. It must have 2, 3 o 4 columns")
Return Nothing
End If
Dim htmlTemplate As New StringBuilder()
Dim tmpFolder As String = Environment.GetEnvironmentVariable("TEMP")
Dim dataSize As Integer = mMarkerData.GetLength(1) 'number of columns
Dim mMarkerDataAsText As String = String.Empty
Dim myresourcePath As String = My.Resources.ResourceManager.BaseName
Dim myresourcefullPath As String = Path.GetFullPath(My.Resources.ResourceManager.BaseName)
Dim localPath = myresourcefullPath.Replace(myresourcePath, "").Replace("\", "/") & ICON_FOLDER
htmlTemplate.AppendLine(getStringFromResources(MAP_TEMPLATE))
mMarkerDataAsText = "["
For i As Integer = 0 To mMarkerData.GetLength(0) - 1
If i <> 0 Then
mMarkerDataAsText += ","
End If
If dataSize = 2 Then 'lat,lon
mMarkerDataAsText += "[" & mMarkerData(i, 0) & "," + mMarkerData(i, 1) & "]"
ElseIf dataSize = 3 Then 'lat,lon and title
mMarkerDataAsText += "[" & mMarkerData(i, 0) & "," + mMarkerData(i, 1) & ",'" & mMarkerData(i, 2) & "']"
ElseIf dataSize = 4 Then 'lat,lon,title and image
mMarkerDataAsText += "[" & mMarkerData(i, 0) & "," + mMarkerData(i, 1) & ",'" & mMarkerData(i, 2) & "','" & localPath & mMarkerData(i, 3) & "']" 'Ojo a las comillas simples en las columnas 3 y 4
End If
Next
mMarkerDataAsText += "]"
htmlTemplate.Replace(TEXT_TO_REPLACE_MARKER_DATA, mMarkerDataAsText)
Dim tmpHtmlMapFile As String = (tmpFolder & Convert.ToString("\")) + TMP_NAME
Dim existsMapFile As Boolean = False
Try
existsMapFile = createTxtFile(tmpHtmlMapFile, htmlTemplate)
Catch ex As Exception
MessageBox.Show("Error writing temporal file", "Writing Error", MessageBoxButtons.OK, MessageBoxIcon.[Error])
End Try
If existsMapFile Then
Return tmpHtmlMapFile
Else
Return Nothing
End If
End Function
Private Function getMarkerDataFromPositions(pos As Double(,)) As String(,)
Dim md As String(,) = New String(pos.GetLength(0) - 1, 1) {}
For i As Integer = 0 To pos.GetLength(0) - 1
md(i, 0) = pos(i, 0).ToString("g", New System.Globalization.CultureInfo("en-US"))
md(i, 1) = pos(i, 1).ToString("g", New System.Globalization.CultureInfo("en-US"))
Next
Return md
End Function
Private Function getStringFromResources(resourceName As String) As String
Dim assem As Assembly = Me.[GetType]().Assembly
Using stream As Stream = assem.GetManifestResourceStream(resourceName)
Try
Using reader As New StreamReader(stream)
Return reader.ReadToEnd()
End Using
Catch e As Exception
Throw New Exception((Convert.ToString("Error de acceso al Recurso '") & resourceName) + "'" & vbCr & vbLf + e.ToString())
End Try
End Using
End Function
Private Function createTxtFile(mFile As String, content As StringBuilder) As Boolean
Dim mPath As String = Path.GetDirectoryName(mFile)
If Not Directory.Exists(mPath) Then
Directory.CreateDirectory(mPath)
End If
If File.Exists(mFile) Then
File.Delete(mFile)
End If
Dim sw As StreamWriter = File.CreateText(mFile)
sw.Write(content.ToString())
sw.Close()
Return True
End Function
End Class
Note: The MAP_TEMPLATE constant must include the name of your project
Step 8. Now we can use our GoogleMapHelper class to load the map into our webbrowser by simply creating and instance and calling its loadMap() method. How you build your markerData is up to you. In this example, for clarification, I write them by hand. There are 3 options to define the marker data (see GoogleMapHelper class comments). Note that if you use the third option (including title and icons) you must create a folder called "marker_icons" (or whatever you define in the GoogleMapHelper constant ICON_FOLDER) in your Debug/Release folder and place there your .png files.
In my case:
I created two buttons in my Form1 to illustrate how the map and the WF interact. Here is how it looks:
And here is the code:
Form1.vb
Imports System.IO
Imports System.Reflection
Imports System.Security.Permissions
Imports System.Text
<PermissionSet(SecurityAction.Demand, Name:="FullTrust")>
<System.Runtime.InteropServices.ComVisible(True)>
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.wbmap.ObjectForScripting = Me
Dim onlyPositions As Double(,) = New Double(2, 1) {{42.13557, -0.40806}, {42.13684, -0.40884}, {42.13716, -0.40729}}
Dim positonAndTitles As String(,) = New String(2, 2) {{"42.13557", "-0.40806", "marker0"}, {"42.13684", "-0.40884", "marker1"}, {"42.13716", "-0.40729", "marker2"}}
Dim positonTitlesAndIcons As String(,) = New String(2, 3) {{"42.13557", "-0.40806", "marker0", "truck_red.png"}, {"42.13684", "-0.40884", "marker1", "truck_red.png"}, {"42.13716", "-0.40729", "marker2", "truck_red.png"}}
'Dim gmh As GoogleMapHelper = New GoogleMapHelper(wbmap, onlyPositions)
'Dim gmh As GoogleMapHelper = New GoogleMapHelper(wbmap, positonAndTitles)
Dim gmh As GoogleMapHelper = New GoogleMapHelper(wbmap, positonTitlesAndIcons)
gmh.loadMap()
End Sub
'############################### CALLING JAVASCRIPT METHODS ##############################
'This methods call methods written in googlemap_template.html
Private Sub callMapJavascript(sender As Object, e As EventArgs) Handles Button1.Click
wbmap.Document.InvokeScript("showJavascriptHelloWorld")
End Sub
Private Sub callMapJavascriptWithArguments(sender As Object, e As EventArgs) Handles Button2.Click
wbmap.Document.InvokeScript("focusMarkerFromIdx", New String() {2})
End Sub
'#########################################################################################
'############################### METHODS CALLED FROM JAVASCRIPT ##########################
'This methods are called by the javascript defined in googlemap_template.html when some events are triggered
Public Sub getMarkerDataFromJavascript(title As String, idx As String)
MsgBox("Title: " & title & " idx: " & idx)
End Sub
Public Sub showVbHelloWorld()
MsgBox("Hello world in WF from HTML")
End Sub
End Class
IMPORTANT : don't forget to add these lines before your class Form1 definition:
<PermissionSet(SecurityAction.Demand, Name:="FullTrust")>
<System.Runtime.InteropServices.ComVisible(True)>
What they do is to tell the .NET Framework that we want fulltrust and make the class visible to COM so Form1 is visible to JavaScript.
Also don't forget this in your Form1 load function:
Me.wbmap.ObjectForScripting = Me
It exposes your Form1 class to the JavaScript on the googlemap_template.hmtl page.
Now you can execute and it should be working
################################# HOW IT WORKS#################################
Basically, what our GoogleMapHelper class does is to read our googlemap_template.html, make a temporal copy, replace the code related to the markers ([[MARKER_DATA]]) and execute the page in the web browser control of our form. This html loops through all the markers and assigns a 'click' listener to each one. This click function is obviously fully customizable. In the example it opens an infowindow if the marker has a title, centers the map in such marker and calls two external functions that are defined in our Form1 class.
On the other hand, we can define other javascript functions (with or without arguments) in this html to be called from our Windows Form (by using wbmap.Document.InvokeScript).
I have use this control and it's really fantastic. It let you use not only GoogleMaps but virtually all the major mapping services, however, the last time I have checked, they have got some licensing troubles with google.
GreatMaps on codeplex
Google Maps API for .NET seeme to be what you are looking for
http://gmaps.codeplex.com/
from the site
This project intends to provide all the features available in the Google Maps API.
It is being developed in C# for .NET Framework 3.5.
Although the project is in C# you can probably just add a reference to the project and use it just like any other reference and write your code in any CLR compliant languege , including VB.
Try this code to get direction between two location
Dim queryaddress As New System.Text.StringBuilder
Dim sStreet As String = String.Empty
Dim sCity As String = String.Empty
Dim sState As String = String.Empty
Dim sPincode As String = String.Empty
Dim sProvider_no As String = String.Empty
queryaddress.Append("https://www.google.com/maps/dir/")
If txtprovider_no.Text <> "" Then
sProvider_no = txtprovider_no.Text.Replace(" ", "+")
queryaddress.Append(sProvider_no + "," & "+")
End If
If txtState.Text <> "" Then
sState = txtState.Text.Replace(" ", "+")
queryaddress.Append(sState + "," & "+")
End If
If txtCity.Text <> "" Then
sCity = txtCity.Text.Replace(" ", "+")
queryaddress.Append(sCity + "," & "+")
End If
If txtPincode.Text <> "" Then
sPincode = txtPincode.Text.Replace(" ", "+")
queryaddress.Append(sPincode)
End If
queryaddress.Append("/")
sStreet = String.Empty
sCity = String.Empty
sState = String.Empty
sPincode = String.Empty
If txtlindmark.Text <> "" Then
sStreet = txtlindmark.Text.Replace(" ", "+")
queryaddress.Append(sStreet + "," & "+")
End If
If txtclient_city.Text <> "" Then
sCity = txtclient_city.Text.Replace(" ", "+")
queryaddress.Append(sCity + "," & "+")
End If
If ttxtclient_city.Text <> "" Then
sPincode = ttxtclient_city.Text.Replace(" ", "+")
queryaddress.Append(sPincode)
End If
If txtclient_state.Text <> "" Then
sState = txtclient_state.Text.Replace(" ", "+")
queryaddress.Append(sState + "," & "+")
End If
WBR.Navigate(queryaddress.ToString())
The Google Maps Control 2017 project wraps Google Maps API as ASP.NET Custom Control, providing an easy and fast way of adding Google Maps in your ASP.NET C# or VB pages with "Zero-Written-JavaScript" code.
ASP.NET Google Maps Control includes many features (markers, polyline, polygons, directions) and gives you almost all Google Maps API functionality in enjoyable ASP.NET way of coding.
PM>Install-Package GoogleMapControl