How do I programmatically change the language used in WinXP using .Net 2.0 (or a pInvoke). The user does not have access to the task bar in the application I'm working on so the input method needs to reflect the application's selected language. I need to be able to swap the language from a left-to-right to a right-to-left and back again without restarting the application. Controls can be re-created though.
The language should be installed in the system, check the following code it's to change the language into Arabic in C#:
public void ToArabic()
{
string CName= "";
foreach(InputLanguage lang in InputLanguage.InstalledInputLanguages)
{
CName = lang.Culture.EnglishName.ToString();
if(CName.StartsWith("Arabic"))
{
InputLanguage.CurrentInputLanguage = lang;
}
}
}
to return it back into English
public void ToEnglish()
{
string CName= "";
foreach(InputLanguage lang in InputLanguage.InstalledInputLanguages)
{
CName = lang.Culture.EnglishName.ToString();
if(CName.StartsWith("English"))
{
InputLanguage.CurrentInputLanguage = lang;
}
}
}
you can use this code in your application to change the input language.
Also the user can press alt + shift to change between the defined language in the system.
Related
I followed the documentation and using resx files with displaying correct language, with DI on Android, I am able to change language within my app.
Basically in Android, I added platform specific code as described in the article
`[assembly:Dependency(typeof(UsingResxLocalization.Android.Localize))]
namespace UsingResxLocalization.Android
{
public class Localize : UsingResxLocalization.ILocalize
{
public void SetLocale(CultureInfo ci)
{
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
}
public CultureInfo GetCurrentCultureInfo()
{
var netLanguage = "en";
var androidLocale = Java.Util.Locale.Default;
netLanguage = AndroidToDotnetLanguage(androidLocale.ToString().Replace("_", "-"));
// this gets called a lot - try/catch can be expensive so consider caching or something
System.Globalization.CultureInfo ci = null;
try
{
ci = new System.Globalization.CultureInfo(netLanguage);
}
catch (CultureNotFoundException e1)
{
// iOS locale not valid .NET culture (eg. "en-ES" : English in Spain)
// fallback to first characters, in this case "en"
try
{
var fallback = ToDotnetFallbackLanguage(new PlatformCulture(netLanguage));
ci = new System.Globalization.CultureInfo(fallback);
}
catch (CultureNotFoundException e2)
{
// iOS language not valid .NET culture, falling back to English
ci = new System.Globalization.CultureInfo("en");
}
}
return ci;
}
string AndroidToDotnetLanguage(string androidLanguage)
{
var netLanguage = androidLanguage;
//certain languages need to be converted to CultureInfo equivalent
switch (androidLanguage)
{
case "ms-BN": // "Malaysian (Brunei)" not supported .NET culture
case "ms-MY": // "Malaysian (Malaysia)" not supported .NET culture
case "ms-SG": // "Malaysian (Singapore)" not supported .NET culture
netLanguage = "ms"; // closest supported
break;
case "in-ID": // "Indonesian (Indonesia)" has different code in .NET
netLanguage = "id-ID"; // correct code for .NET
break;
case "gsw-CH": // "Schwiizertüütsch (Swiss German)" not supported .NET culture
netLanguage = "de-CH"; // closest supported
break;
// add more application-specific cases here (if required)
// ONLY use cultures that have been tested and known to work
}
return netLanguage;
}
string ToDotnetFallbackLanguage(PlatformCulture platCulture)
{
var netLanguage = platCulture.LanguageCode; // use the first part of the identifier (two chars, usually);
switch (platCulture.LanguageCode)
{
case "gsw":
netLanguage = "de-CH"; // equivalent to German (Switzerland) for this app
break;
// add more application-specific cases here (if required)
// ONLY use cultures that have been tested and known to work
}
return netLanguage;
}
}
}`
In PCL code I have
namespace myApp.Resx
{
/// <summary>
/// Implementations of this interface MUST convert iOS and Android
/// platform-specific locales to a value supported in .NET because
/// ONLY valid .NET cultures can have their RESX resources loaded and used.
/// </summary>
/// <remarks>
/// Lists of valid .NET cultures can be found here:
/// http://www.localeplanet.com/dotnet/
/// http://www.csharp-examples.net/culture-names/
/// You should always test all the locales implemented in your application.
/// </remarks>
public interface ILocalize
{
/// <summary>
/// This method must evaluate platform-specific locale settings
/// and convert them (when necessary) to a valid .NET locale.
/// </summary>
CultureInfo GetCurrentCultureInfo();
/// <summary>
/// CurrentCulture and CurrentUICulture must be set in the platform project,
/// because the Thread object can't be accessed in a PCL.
/// </summary>
void SetLocale(CultureInfo ci);
}
/// <summary>
/// Helper class for splitting locales like
/// iOS: ms_MY, gsw_CH
/// Android: in-ID
/// into parts so we can create a .NET culture (or fallback culture)
/// </summary>
public class PlatformCulture
{
public PlatformCulture(string platformCultureString)
{
if (String.IsNullOrEmpty(platformCultureString))
throw new ArgumentException("Expected culture identifier", "platformCultureString"); // in C# 6 use nameof(platformCultureString)
PlatformString = platformCultureString.Replace("_", "-"); // .NET expects dash, not underscore
var dashIndex = PlatformString.IndexOf("-", StringComparison.Ordinal);
if (dashIndex > 0)
{
var parts = PlatformString.Split('-');
LanguageCode = parts[0];
LocaleCode = parts[1];
}
else
{
LanguageCode = PlatformString;
LocaleCode = "";
}
}
public string PlatformString { get; private set; }
public string LanguageCode { get; private set; }
public string LocaleCode { get; private set; }
public override string ToString()
{
return PlatformString;
}
}
}
then in my PCL code, I am able to overwrite the culture with the code below
string name = Helpers.Settings.PreferredLanguage == "en" ? "en-US" : Helpers.Settings.PreferredLanguage + "-" + Helpers.Settings.PreferredLanguage.ToUpper();
currentCultureInfo = new System.Globalization.CultureInfo(name);
Xamarin.Forms.DependencyService.Get<Resx.ILocalize>().SetLocale(currentCultureInfo);
Resx.AppRes.Culture = currentCultureInfo;
This Code implementation works fine when I run in Debug and Release Mode.
But It fails working in Release Mode using "Bundle Assemblies into Native Code".
If I remove the check for this option, It works fine.
What could be the possible problem? I dont know how to track this down. I tried using Android Device Monitor but it doesnt display much for it.
configuration looks like as above.
EDIT: when I enable, "Enable developer instrumentation" in Release mode, It works also.
Obviously there is already an existing bug for this issue on the link. Until bug is fixed by xamarin, workaround is as suggested on the link. add a line for each language in OnCreate function of MainActivity
System.Reflection.Assembly.LoadFile("de-DE\\AppName.resources.dll");
Is there a reliable, programmatic way to determine that Microsoft Edge is the default browser?
I know one option would be to use the IApplicationAssociationRegistration::QueryCurrentDefault method to return the default application registered for http. It's unclear that the ProgID returned by this call is a fixed string though so it may not be the best way to verify that Edge is indeed the default browser.
Use the following code snippet. Haven't tested with Firefox or any of the other strange ones, but you'll get the following return values based on your default browser in Windows 10.
Chrome - ChromeHTML
Edge - AppXq0fevzme2pys62n3e0fbqa7peapykr8v
Internet Explorer - IE.HTTP
Code snippet below should work. Tested in a console app. If anyone wants a VB version let me know.
using Microsoft.Win32;
public static class BrowserUtils
{
static public string GetSystemDefaultBrowser()
{
string _retval = string.Empty;
const string userChoice = #"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice";
using (RegistryKey userChoiceKey = Registry.CurrentUser.OpenSubKey(userChoice))
{
if (userChoiceKey == null)
{
_retval = "unknown-> userChoiceKey returned null";
}
object progIdValue = userChoiceKey.GetValue("Progid");
if (progIdValue == null)
{
_retval = "unknown->GetValue(Progid) returned null";
}
//_retval = String.Format("progId=[{0}]", progIdValue.ToString());
_retval = progIdValue.ToString();
}
return _retval;
}
}
Hope this helps. Healy in Tampa.
Taking as a start point the JSF2 internationalization example of this link:
http://www.mkyong.com/jsf2/jsf-2-internationalization-example/
I want this example to display the language of the combos in the actual language selected.
Could somebody point me how this can be done?
Thanks!
It's just a matter of setting the proper labels in the static variable countries:
static {
countries = new LinkedHashMap<String,Object>();
countries.put("English", Locale.ENGLISH); //label, value
countries.put("Deutsch", Locale.GERMAN);
countries.put("Français", Locale.FRENCH);
// ... fill in with additional languages/locales as needed
}
You can get a bigger list of language names in their original language here: http://www.omniglot.com/language/names.htm
UPDATE: According to OP's comment, he needs the language names translated to every language. For that, one could come up with a solution simply making a map of language maps (that's quite a few maps), like this:
// set a default value for localeCode
private String localeCode = Locale.ENGLISH.toString();
// ...
static {
countries = new LinkedHashMap<Object, <String,Object>>();
englishCountries = new LinkedHashMap<String,Object>();
englishCountries.put("English", Locale.ENGLISH); //label, value
englishCountries.put("German", Locale.GERMAN);
englishCountries.put("French", Locale.FRENCH);
countries.put(Locale.ENGLISH, englishCountries);
germanCountries = new LinkedHashMap<String,Object>();
germanCountries.put("Englisch", Locale.ENGLISH);
germanCountries.put("Deutsch", Locale.GERMAN);
germanCountries.put("Französisch", Locale.FRENCH);
countries.put(Locale.GERMAN, germanCountries);
frenchCountries = new LinkedHashMap<String,Object>();
frenchCountries.put("Anglais", Locale.ENGLISH);
frenchCountries.put("Allemand", Locale.GERMAN);
frenchCountries.put("Français", Locale.FRENCH);
countries.put(Locale.FRENCH, frenchCountries);
// ... fill in with additional languages/locales as needed
}
public Map<Object, <String,Object>> getCountriesInMap() {
return countries;
}
// adapted value change listener from original:
public void countryLocaleCodeChanged(ValueChangeEvent e){
String newLocaleValue = e.getNewValue().toString();
//loop country map to compare the locale code
for (Object key : countries.keySet()) {
if (key.toString().equals(newLocaleValue)) {
FacesContext.getCurrentInstance().getViewRoot()
.setLocale((Locale) key);
}
}
}
and then you would choose the proper map to be used for the selectItems, with something like this:
<h:selectOneMenu value="#{language.localeCode}" onchange="submit()"
valueChangeListener="#{language.countryLocaleCodeChanged}">
<f:selectItems value="#{language.countriesInMap[language.localeCode]}" />
</h:selectOneMenu>
Note: Don't forget to set a default value for language.localeCode, or the dropdown won't show any options
Please note, though, that this is probably NOT a good idea for usability, since a user who chooses a foreign language by mistake may have a hard time to get back to a known language for her (that's why it's a good practice to make the lists have the language names in each own language).
How can I (in ASP .NET MVC) get the CultureInfo of the current visitor (based on his/her browser languages)?
I have no idea where to start. I tried looking into the "Accept-Languages" header sent by the browser. But is that the best way of doing it?
Request.UserLanguages is the property you're looking for. Just keep in mind that this array may contain arbitrary (even non-exsitent) languages as set by request headers.
UPDATE
Example:
// Get Browser languages.
var userLanguages = Request.UserLanguages;
CultureInfo ci;
if (userLanguages.Count() > 0)
{
try
{
ci = new CultureInfo(userLanguages[0]);
}
catch(CultureNotFoundException)
{
ci = CultureInfo.InvariantCulture;
}
}
else
{
ci = CultureInfo.InvariantCulture;
}
// Here CultureInfo should already be set to either user's prefereable language
// or to InvariantCulture if user transmitted invalid culture ID
Asp.Net Core version: using RequestLocalization ie the culture is retrieved form the HTTP Request.
in Startup.cs - Configure
app.UseRequestLocalization();
Then in your Controller/Razor Page.cs
var locale = Request.HttpContext.Features.Get<IRequestCultureFeature>();
var BrowserCulture = locale.RequestCulture.UICulture.ToString();
You can use code similar to the following to get various details from your user (including languages):
MembershipUser user = Membership.GetUser(model.UserName);
string browser = HttpContext.Request.Browser.Browser;
string version = HttpContext.Request.Browser.Version;
string type = HttpContext.Request.Browser.Type;
string platform = HttpContext.Request.Browser.Platform;
string userAgent = HttpContext.Request.UserAgent;
string[] userLang = HttpContext.Request.UserLanguages
It appears Request.UserLanguages is not available in later mvc versions (Asp.net core mvc 2.0.2 didn't have it.)
I made an extension method for HTTPRequest. Use it as follows:
var requestedLanguages = Request.GetAcceptLanguageCultures();
The method will give you the cultures from the Accept-Language header in order of preference (a.k.a. "quality").
public static class HttpRequestExtensions
{
public static IList<CultureInfo> GetAcceptLanguageCultures(this HttpRequest request)
{
var requestedLanguages = request.Headers["Accept-Language"];
if (StringValues.IsNullOrEmpty(requestedLanguages) || requestedLanguages.Count == 0)
{
return null;
}
var preferredCultures = requestedLanguages.ToString().Split(',')
// Parse the header values
.Select(s => new StringSegment(s))
.Select(StringWithQualityHeaderValue.Parse)
// Ignore the "any language" rule
.Where(sv => sv.Value != "*")
// Remove duplicate rules with a lower value
.GroupBy(sv => sv.Value).Select(svg => svg.OrderByDescending(sv => sv.Quality.GetValueOrDefault(1)).First())
// Sort by preference level
.OrderByDescending(sv => sv.Quality.GetValueOrDefault(1))
.Select(sv => new CultureInfo(sv.Value.ToString()))
.ToList();
return preferredCultures;
}
}
Tested with ASP.NET Core MVC 2.0.2
It's similar to #mare's answer, but a bit more up-to-date and the q (quality) is not ignored. Also, you may want to append the CultureInfo.InvariantCulture to the end of the list, depending on your usage.
I am marking this question for myself with a star and sharing here some code that essentially turns the Request.UserLanguages into an array of CultureInfo instances for further use in your application. It is also more flexible to work with CultureInfo than just the ISO codes, because with CultureInfo you get access to all the properties of a culture (like Name, Two character language name, Native name, ...):
// Create array of CultureInfo objects
string locale = string.Empty;
CultureInfo[] cultures = new CultureInfo[Request.UserLanguages.Length + 1];
for (int ctr = Request.UserLanguages.GetLowerBound(0); ctr <= Request.UserLanguages.GetUpperBound(0);
ctr++)
{
locale = Request.UserLanguages[ctr];
if (!string.IsNullOrEmpty(locale))
{
// Remove quality specifier, if present.
if (locale.Contains(";"))
locale = locale.Substring(0, locale.IndexOf(';'));
try
{
cultures[ctr] = new CultureInfo(locale, false);
}
catch (Exception) { continue; }
}
else
{
cultures[ctr] = CultureInfo.CurrentCulture;
}
}
cultures[Request.UserLanguages.Length] = CultureInfo.InvariantCulture;
HTH
var userLanguage = CultureInfo.CurrentUICulture;
Ok,
For the past 6 months i've been struggeling to build a system that allows user input in form of big sexy textareas(with loads of support for tables,list etc). Pretty much enables the user to input data as if it were word. However when wanting to export all this data I haven't been able to find a working solution...
My first step was to try and find a reporting software that did support raw HTML from the data source and render it as normal html, worked perfectly except that the keep together function is awful, either data is split in half(tables,lists etc) which I dont want. Or report always skips to the next page to avoid this, ending up in 15+ empty pages within the final document.
So Im looking for some kind of tip/direction to what would be the best solution to export my data into a readable document(pdf or word pref).
What I got is the following data breakdown, where data is often raw html.
-Period
--Unit
---Group
----Question
-----Data
What would be the best choice? Trying to render html to pdf or rtf? I need tips :(
And also sometimes the data is 2-3 pages long with mixed tables lists and plain text.
I would suggest that you try to keep this in the browser, and add a print stylesheet to the HTML to make it render one way on the screen and another way on paper. Adding a print stylesheet to your HTML is as easy as this:
<link rel="stylesheet" media="print" href="print.css">
You should be able to parse the input it with something like Html Agility Pack and transform it (i.e. with XSLT) to whatever output format you want.
Another option is to write HTML to the browser, but with Content-Type set to a Microsoft Word-specific variant (there are several to choose from, depending on the version of Word you're targeting) should make the browser ask if the user wants to open the page with Microsoft Word. With Word 2007 and newer you can also write Office Open XML Word directly, since it's XML-based.
The content-types you can use are:
application/msword
For binary Microsoft Word files, but should also work for HTML.
application/vnd.openxmlformats-officedocument.wordprocessingml.document
For the newer "Office Open XML" formats of Word 2007 and newer.
A solution you could use is to run an application on the server using System.Diagnostics.Process that will convert the site and save it as a PDF document.
You could use wkhtmltopdf which is an open source console program that can convert from HTML to PDF or image.
The installer for windows can be obtained from wkhtmltox-0.10.0_rc2 Windows Installer (i368).
After installing wkhtmltopdf you can copy the files in the installation folder inside your solution. You can use a setup like this in the solution:
The converted pdf's will be saved to the pdf folder.
And here is code for doing the conversion:
var wkhtmltopdfLocation = Server.MapPath("~/wkhtmltopdf/") + "wkhtmltopdf.exe";
var htmlUrl = #"http://stackoverflow.com/q/7384558/750216";
var pdfSaveLocation = "\"" + Server.MapPath("~/wkhtmltopdf/pdf/") + "question.pdf\"";
var process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.FileName = wkhtmltopdfLocation;
process.StartInfo.Arguments = htmlUrl + " " + pdfSaveLocation;
process.Start();
process.WaitForExit();
The htmlUrl is the location of the page you need to convert to pdf. It is set to this stackoverflow page. :)
Its a general question, but two things come to mind the Visitor Pattern and Changing the Mime Type.
Visitor Pattern
You can have two seperate rendering techniques. This would be up to your implementation.
MIME Type
When the request is made write date out in the Response etc
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Charset = "utf-16";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1250");
HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}.doc", filename));
HttpContext.Current.Response.ContentType = "application/msword";
HttpContext.Current.Response.Write("-Period");
HttpContext.Current.Response.Write("/n");
HttpContext.Current.Response.Write("--Unit");
HttpContext.Current.Response.Write("/n");
HttpContext.Current.Response.Write("---Group");
HttpContext.Current.Response.Write("/n");
HttpContext.Current.Response.Write("----Question");
HttpContext.Current.Response.Write("/n");
HttpContext.Current.Response.Write("-----Data");
HttpContext.Current.Response.Write("/n");
HttpContext.Current.Response.End();
Here is another option, use print screens (Although it doesnt take care of scrolling, I think you should be able to build this in). This example can be expanded to meet the needs of your business, although it is a hack of sorts. You pass it a URL it generates an image.
Call like this
protected void Page_Load(object sender, EventArgs e)
{
int screenWidth = Convert.ToInt32(Request["ScreenWidth"]);
int screenHeight = Convert.ToInt32(Request["ScreenHeight"]);
string url = Request["Url"].ToString();
string bitmapName = Request["BitmapName"].ToString();
WebURLToImage webUrlToImage = new WebURLToImage()
{
Url = url,
BrowserHeight = screenHeight,
BrowserWidth = screenWidth,
ImageHeight = 0,
ImageWidth = 0
};
webUrlToImage.GenerateBitmapForUrl();
webUrlToImage.GeneratedImage.Save(Server.MapPath("~") + #"Images\" +bitmapName + ".bmp");
}
Generate an image from a webpage.
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.IO;
public class WebURLToImage
{
public string Url { get; set; }
public Bitmap GeneratedImage { get; private set; }
public int ImageWidth { get; set; }
public int ImageHeight { get; set; }
public int BrowserWidth { get; set; }
public int BrowserHeight { get; set; }
public Bitmap GenerateBitmapForUrl()
{
ThreadStart threadStart = new ThreadStart(ImageGenerator);
Thread thread = new Thread(threadStart);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
return GeneratedImage;
}
private void ImageGenerator()
{
WebBrowser webBrowser = new WebBrowser();
webBrowser.ScrollBarsEnabled = false;
webBrowser.Navigate(Url);
webBrowser.DocumentCompleted += new
WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);
while (webBrowser.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
webBrowser.Dispose();
}
void webBrowser_DocumentCompleted(object sender,
WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser webBrowser = (WebBrowser)sender;
webBrowser.ClientSize = new Size(BrowserWidth, this.BrowserHeight);
webBrowser.ScrollBarsEnabled = false;
GeneratedImage = new Bitmap(webBrowser.Bounds.Width, webBrowser.Bounds.Height);
webBrowser.BringToFront();
webBrowser.DrawToBitmap(GeneratedImage, webBrowser.Bounds);
if (ImageHeight != 0 && ImageWidth != 0)
GeneratedImage =
(Bitmap)GeneratedImage.GetThumbnailImage(ImageWidth, ImageHeight,
null, IntPtr.Zero);
}
}