We want to integrate Google maps into our C/C++ win32 application.
The whole idea is when user runs the application for the first time we request them to mark their location and then retrieve the coordinates of the user selected location and save into a database or file.
After it has been initialized we want to provide user with some pre tagged places and allow user to find direction from their place to that place. The coordinates of the pre tagged locations will be provided.
Is it possible to achieve what we want by using Google Api's, if yes then how??
And if there are legal issues regarding it??
Thanks.
For the answer to the legal question, the best place is to look at the Terms of Service, and then to consult a lawyer of course. Both terms of service for the Maps API as well as the Maps for Business Terms of Service explicitly prohibit the usage of geocoding data if it is not in conjunction with a Google Map:
Maps API TOS, relevant point is Section 10.1.1 (g):
https://developers.google.com/maps/terms#section_10_1
Business Maps Purchase Agreement, relevant point is 4.1 (l):
https://www.google.com/enterprise/earthmaps/legal/us/maps_purchase_agreement.html
If you need a more liberal alternative you might want to look at http://www.openstreetmap.org/ - the geocoding data offered there is covered under the Open Database License, which permits usage with attribution.
http://wiki.openstreetmap.org/wiki/Legal_FAQ
You can use Qt framework on Windows. You can integrate your win32 application with Qt. In Qt you may use QWebKit framework to communicate with your app and a webpage(which, in this scenario is a page containing a map from Google Maps) . Actually you can write hybrid applications with Qt. Take a look at Qt QWebKit documentation.
I needed the same and solved it by interfacing Google Maps via a Browser object.
*** Please read about WebBrowser control compatibility and follow the instructions.
Create an MFC dialog based project.
Add a CExplorer control. (See: https://msdn.microsoft.com/en-us/library/aa752046(v=vs.85).aspx).
When the main dialog of your program initializes, you need to initialize a global object
CExplorer1 m_Browser;
The first building block would be WriteHTML()
void WriteHTML(const wchar_t* html)
{
IDispatch* pHtmlDoc = m_Browser.get_Document();
if (!pHtmlDoc)
return;
CComPtr<IHTMLDocument2> doc1 = NULL;
doc1.Detach();
doc1.Attach((IHTMLDocument2*)pHtmlDoc);
if (!doc1)
return;
// Creates a new one-dimensional array
SAFEARRAY* psaStrings = SafeArrayCreateVector(VT_VARIANT, 0, 1);
if (!psaStrings)
return;
BSTR bstr = SysAllocString(html);
if (bstr)
{
VARIANT* param;
HRESULT hr = SafeArrayAccessData(psaStrings, (LPVOID*)¶m);
if (SUCCEEDED(hr))
{
param->vt = VT_BSTR;
param->bstrVal = bstr;
hr = SafeArrayUnaccessData(psaStrings);
if (SUCCEEDED(hr))
{
doc1->write(psaStrings);
doc1->close();
}
}
}
// SafeArrayDestroy calls SysFreeString for each BSTR!
if (psaStrings)
SafeArrayDestroy(psaStrings);
}
You should also add the browser control to your .rs file
CONTROL "",IDC_SGWEBBROWSER,"{8856F961-340A-11D0-A96B-
00C04FD705A2}",WS_TABSTOP,388,36,236,281
Among several ways to implement it, I found that creating a temporary HTML based on the coordinates and calling: m_Browser.Navigate(FileName, 0, 0, 0, 0);
is the best.
"FileName" is created based on the requested coordinates of the point on the map, along with other attributes as follow:
Assign a name and path to "FileName":
wchar_t FileName[2048];
GetCurrentDirectory(2048, FileName);
wcscat(FileName, L"\\test.html");
Filling the file with data and opening it with the browser control, whilst navigating Google Maps to the requested location:
Variables:
a. Latitude
b. Longitude
c. zoom (set to 10)
d. API key. (you need to obtain one)
Code (an alternative to the WriteHTML function)
CString HTML_TEXT;
CRect rect;
CWnd *pWnd = GetDlgItem(IDC_SGWEBBROWSER);
pWnd->GetWindowRect(&rect);
int w = rect.Width()-50, h = rect.Height()-50;
HTML_TEXT.Format(L"<!DOCTYPE html><html><meta http-equiv=\"X - UA - Compatible\" content=\"IE = edge\"><body><div id =\"googleMap\" style=\"width:%dpx;height:%dpx\"><script>function myMap(){var mapProp = {center:new google.maps.LatLng(%f, %f), zoom : 10};var map = new google.maps.Map(document.getElementById(\"googleMap\"), mapProp);marker = new google.maps.Marker({position: new google.maps.LatLng(%f, %f),map: map});}</script><script src = \"https://maps.googleapis.com/maps/api/js?key=%s&callback=myMap\"></script></div></body></html>", w, h, Latitude, Longitude, Latitude, Longitude, API_KEY);
FILE *fp = _wfopen(FileName, L"w");
fwprintf(fp, L"%s", HTML_TEXT.GetBuffer());
fclose(fp);
m_Browser.Navigate(FileName, 0, 0, 0, 0);
Related
I'm new to using codename one and I can not understand how we can take a picture from the camera using captureImage (); from the camerakit library.
I know it's possible with the Capture API (Capture.capturePhoto ();) but this library uses an application to take the photo and I want to do this directly
I created a button :
FloatingActionButton capture_button =
FloatingActionButton.createFAB(FontImage.MATERIAL_CAMERA);
capture_button.bindFabToContainer(hi, CENTER, BOTTOM);
capture_button.addActionListener(e -> {
ck.captureImage();
.............
and after that I tried to get my picture from the onImage function but it does not work.
#Override
public void onImage(CameraEvent ev) {
try {
byte[] jpegData = ev.getJpeg();
String str = new String(jpegData);
InputStream stream = FileSystemStorage.getInstance().openInputStream(jpegData);
OutputStream out = Storage.getInstance().createOutputStream("MyImage.jpg");
Util.copy(stream, out);
Util.cleanup(stream);
Util.cleanup(out);
StorageImage out = StorageImage.create("MyImage.jpg", jpegData, -1, -1);
............................
}
the byte array is empty. Help please.
Camera Kit broke a bit after its release due to changes in Camera Kit which is still not 1.0 level. This is tracked in this issue. Camera kit was supposed to reach 1.0 status months ago but still hasn't reached that point. We
are waiting for it to be at 1.0 level so we can make fixes against a stable version.
We also need a bit of time/resources to do that work which is something we are sorely lacking.
I'd like to access the Google Calendar of a user after Login, since I want to mirror certain labeled events in my Apps event class.
I guess the Google Calendar API Java Library can't be simply used here, so I was sent to this Library by the Codename One Support.
Does anyone have experience or Code examples for this Library?
How did you guys handle access to Google Calendar API if not with this library?
I did some of the initial work on that but haven't kept up with the changes done by the other authors so I can't say I have actual experience with this library...
From the code something like this should work:
DeviceCalendar dc = DeviceCalendar.getInstance();
if(!dc.hasPermissions()) {
// show message
return;
}
String calName = Preferences.get("selectedCalendar", null);
if(calName == null) {
Collection<String> calendarNames = dc.getCalendars()
calName = promptUserToPickCalendar(calendarNames);
if(calName == null) {
return;
}
Preferences.set("selectedCalendar", calName);
}
String calId = dc.openCalendar(calName, false);
Collection<EventInfo> events = dc.getEvents(calId, startDate, endDate);
// merge your events then use removeEvent/saveEvent respectively to apply your changes
I want to write an application that will automatically detect and fill the text field in the window shown below:
(assuming the data to be entered is in a file).
The question is how does my application find this text field?
I can do this job if I am able to find the location of the text field on the desktop through program.
Can someone help me understand possible ways for finding this text field?
I am using Windows Form application in C++.
Update:
I played with spy++.
I used spy++, to find the window handle. I did it by putting finder on the window I am interested in. Its giving handle in hex values: 00080086 (actually just for testing purpose I put the finder tool on Visual Studio new project page ). How do I interpret this Hex value into meaningful window name ?
See the below figure.
What is the next step to get to the text field " Enter name" under "name" field.
****Any sample code will be highly appreciated.**
I am open to any solution not necessarily how I am doing this.
One solution is to use the Microsoft UI Automation technology. It's shipped out-of-the-box with Windows since Vista. It's usable from .NET but also from C++ using COM.
Here is a short C++ console application example that displays the class name of the UI Automation Element currently at the middle of the desktop window, each second (you can have it run and see what it displays):
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
IUIAutomation *pAutomation; // requires Uiautomation.h
HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (LPVOID *)&pAutomation);
if (SUCCEEDED(hr))
{
RECT rc;
GetWindowRect(GetDesktopWindow(), &rc);
POINT center;
center.x = (rc.right - rc.left) / 2;
center.y = (rc.bottom - rc.top) / 2;
printf("center x:%i y:%i'\n", center.x, center.y);
do
{
IUIAutomationElement *pElement;
hr = pAutomation->ElementFromPoint(center, &pElement);
if (SUCCEEDED(hr))
{
BSTR str;
hr = pElement->get_CurrentClassName(&str);
if (SUCCEEDED(hr))
{
printf("element name:'%S'\n", str);
::SysFreeString(str);
}
pElement->Release();
}
Sleep(1000);
}
while(TRUE);
pAutomation->Release();
}
CoUninitialize();
return 0;
}
From this sample, what you can do is launch the application you want to automate and see if the sample detects it (it should).
You could also use the UISpy tool to display the full tree of what can be automated in your target app. You should see the windows and other elements (text field) of this target app and you should see the element displayed by the console application example.
From the pElement discovered in the sample, you can call FindFirst with the proper condition (class name, name, control type, etc...) to get to the text field. From this text field, you would use one of the UI Automation Patterns that should be available (probably TextPattern or ValuePattern) to get or set the text itself.
The cool thing is you can use the UISpy tool to check all this is possible before actually coding it.
You could enumerate windows and then find it.
For exploring application on your screenshot you could you Spy++ (spyxx.exe) that is distributed with visual studio. In you code, you clould use EnumWindows and EnumChildWindows to enumerates all window or all child windows to find one you need.
Although the answer given by Simon is accepted and is the best one, but still for future visitors I am providing this link which has more description for UI automation of windows applications. .
Also for automating a web application one may want to go to this link
I have the following requirement for a business application:
(All of this could be on local or server)
Allow user to select folder location
Show contents of folder
Print selected items from folder (*.pdf)
Display which files have been printed
Potentially move printed files to new location (sub-folder of printed)
How can I make this happen in Silverlight?
Kind regards,
ribald
First of all, all but the last item can be done (the way you expect). Due to security protocols, silverlight cannot access the user's drive and manipulate it. The closest you can get is accessing silverlight's application storage which will be of no help to you whatsoever in this case. I will highlight how to do the first 4 items.
Allow user to select folder location & Show contents of folder
public void OnSelectPDF(object sender)
{
//create the open file dialog
OpenFileDialog ofg = new OpenFileDialog();
//filter to show only pdf files
ofg.Filter = "PDF Files|*.pdf";
ofg.ShowDialog();
byte[] _import_file = new byte[0];
//once a file is selected proceed
if (!object.ReferenceEquals(ofg.File, null))
{
try
{
fs = ofg.File.OpenRead();
_import_file = new byte[fs.Length];
fs.Read(_import_file, 0, (int)fs.Length);
}
catch (Exception ex)
{
}
finally
{
if (!object.ReferenceEquals(fs, null))
fs.Close();
}
//do stuff with file - such as upload the file to the server
};
}
If you noticed, in my example, once the file is retrieved, i suggest uploading it to a webserver or somewhere with temporary public access. I would recommend doing this via a web service. E.g
//configure the system file (customn class)
TSystemFile objFile = new TNetworkFile().Initialize();
//get the file description from the Open File Dialog (ofg)
objFile.Description = ofg.File.Extension.Contains(".") ? ofg.File.Extension : "." + ofg.File.Extension;
objFile.FileData = _import_file;
objFile.FileName = ofg.File.Name;
//upload the file
MasterService.ToolingInterface.UploadTemporaryFileAsync(objFile);
Once this file is uploaded, on the async result, most likely returning the temporary file name and upload location, I would foward the call to some javascript method in the browser for it to use the generic "download.aspx?fileName=givenFileName" technique to force a download on the users system which would take care of both saving to a new location and printing. Which is what your are seeking.
Example of the javascript technique (remember to include System.Windows.Browser):
public void OnInvokeDownload(string _destination)
{
//call the browser method/jquery method
//(I use constants to centralize the names of the respective browser methods)
try
{
HtmlWindow window = HtmlPage.Window;
//where BM_INVOKE_DOWNLOAD is something like "invokeDownload"
window.Invoke(Constants.TBrowserMethods.BM_INVOKE_DOWNLOAD, new object[] { _destination});
}
catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); }
}
Ensure you have the javascript method existing either in an included javaScript file or in the same hosting page as your silverlight app. E.g:
function invokeDownload(_destination) {
//some fancy jquery or just the traditional document.location change here
//open a popup window to http://www.myurl.com/downloads/download.aspx? fileName=_destination
}
The code for download.aspx is outside the scope of my answer, as it varies per need and would just lengthen this post (A LOT MORE). But from what I've given, it will "work" for what you're looking for, but maybe not in exactly the way you expected. However, remember that this is primarily due to silverlight restrictions. What this approach does is rather than forcing you to need a pluging to view pdf files in your app, it allows the user computer to play it's part by using the existing adobe pdf reader. In silverlight, most printing, at least to my knowledge is done my using what you call and "ImageVisual" which is a UIElement. To print a pdf directly from silverlight, you need to either be viewing that PDF in a silverlight control, or ask a web service to render the PDF as an image and then place that image in a control. Only then could you print directly. I presented this approach as a lot more clean and direct approach.
One note - with the temp directory, i would recommend doing a clean up by some timespan of the files on the server side everytime a file is being added. Saves you the work of running some task periodically to check the folder and remove old files. ;)
Am currently developing a GPS powered solution for tracking field units, and I plan to use Samsung's BADA OS powered phones (affordable but powerful). The only problem am now facing, is i don't know the easiest way to obtain GPS info from the phone (a GT-S5333) to a server (probably via a GET). What can I do?
I've searched for available options and they might not be very friendly as this app doesn't even require an interface on the phone, just sending of the GPS info to a server. Samsung provides a C++ api for Bada (but I think this might be over-kill for this sort of task.)
The other option might be using Webwag's widget api, but I've tried it already, and it doesn't even seem to be possible to do anything beyond RSS widgets.
Might someone help?
Eventually, I did learn about the possibility of using J2ME's Location API, and indeed it is supported on Bada OS phones (virtually any modern phone). So I went for it, and this is how I would obtain my device's location:
import javax.microedition.location.*;
private String reportLocation(Form mainForm){
Criteria cr= new Criteria();
cr.setHorizontalAccuracy(500);
final LocationProvider lp= LocationProvider.getInstance(cr);
new Thread(){
public void run(){
lp.setLocationListener(PatrolGPSDevice.this, 30, -1, -1);
}
}.start();
Location l = lp.getLocation(60);
Coordinates c = l.getQualifiedCoordinates();
if(c != null ) {
double lat = c.getLatitude();
double lon = c.getLongitude();
//do what I want with the location data -- in this case, send it to a server
}