.NET COM usercontrol does not set font or language properly - vb.net

I have created a COM VB.NET (v3.5 under VS2013) usercontrol which i have included in an old VB6 project. The control communicates with its VB6 host just fine. It works as expected, opens the DB, reads / writes stuff. Everything is OK except one thing, which i'm not sure what it is. It seems i cannot properly set either its font(?) or its language(?) to Greek in order to be able to type Greek characters in a contained textbox.
This usercontrol contains several other .NET controls. Listboxes, buttons and textboxes. I read stuff from DB, set the text property of all those controls to the contents of the database and Greek are shown properly. If i try to switch the O/S language to Greek and type something in a textbox, strange characters are shown instead of the proper Greek ones (i assume from another codepage). I have programmatically changed its font to "[Font: Name=Arial, Size=9, Units=3, GdiCharSet=161, GdiVerticalFont=False]". GdiCharSet=161 is Greek. It should work. And it does work from within the .NET environment or from a test .NET exe. I can type Greek in the textbox. When i try to use it from within the VB6 program, it seems switching to Greek and typing Greek chars is not possible. Loading Greek from DB and showing them is no problem though.
I have also tried setting GdiCharSet to 0, 1, 2 (yup, it did show Symbols as expected) and to change the culture in the usercontrol constructor but no luck:
System.Threading.Thread.CurrentThread.CurrentCulture = New System.Globalization.CultureInfo("el-GR")
System.Threading.Thread.CurrentThread.CurrentUICulture = New System.Globalization.CultureInfo("el-GR")
Any ideas someone, what to check / try?

Wow... After spending more hours than i could spare on this matter, i have finally found a solution.
Private Sub txtMessage_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtMessage.KeyPress
If InputLanguage.CurrentInputLanguage.Culture.Equals(New Globalization.CultureInfo("el-GR")) Then
FixKeyChar(e)
End If
End Sub
Public Sub FixKeyChar(ByRef e As KeyPressEventArgs)
Dim myUnicodeBytes As Byte() = Encoding.Unicode.GetBytes(e.KeyChar)
Dim myUTF32Bytes As Byte() = Encoding.Convert(Encoding.Default, Encoding.UTF32, myUnicodeBytes)
e.KeyChar = ChrW(myUTF32Bytes(1) * 256 + myUTF32Bytes(0))
End Sub
I hope it proves to be helpful for some other poor soul messing with these things...

Related

Needing Assistance with vb.NET Application

I don't normally post on forums because I try to find information for myself, and ask as an absolute last resort. I've tried scouring the net for answers, but I'm only receiving about half of the answer I'm looking for.
I'm currently building an application that deals with state law. There's one combo box and one text box. One for the offense title, and one for the numerical code for that particular code section. So say if I select "Kidnapping", it prepopulates the text box below it with "11-5-77", for example.
The method I've been using for, oh, about the last hour now, is:
If AWOffenseTitle.Text = "Kidnapping" Then
AWCN.Text = "11-5-77"
ElseIf AWOffenseTitle.Text = "False Imprisonment" Then
AWCN.Text = "11-5-78"
With AWOffenseTitle being the combo box name, and AWCN being the text box name. While this has proved to work perfectly well so far, I'm sure you can imagine with hundreds of offense titles, this is going to take a ridiculously long time. Well, I finally found a spreadsheet with offense titles and their respective title codes. What I'm looking to do is create two text files within a folder in the local directory "Offenses". One with a vertical list of offenses, and one with a vertical list of offense code numbers that populate the same lines in each. What I'm looking to do is populate the combo box with the contents of text file one (which I can do already), but then selecting an offense title will read the second text file and display it's proper title code. That's what has me at a loss. I'm relatively well-versed with vb.NET, but I'm not an expert by any means.
I'm hoping someone here will be able to provide a code example and explain it to me line-by-line so I can gain a better understanding. I want to get more proficient with VB although it's not so popular anymore. I've been using VB since 6.0, but not on a regular basis. More on a sporadic project kind of basis.
I really appreciate any assistance anyone might be able to provide, and if you need more information, I'd be glad to answer any questions. I tried to be as thorough as I could.
Thank you in advance!
First, you need to retrieve your data. I demonstrated using an Sql Server database containing a table named Offenses with columns named OffenseTitle and OffenseCode. You will have to change this code to match your situation.
Private Function GetOffenseData() As DataTable
Dim dt As New DataTable
Using cn As New SqlConnection("Your connection string"),
cmd As New SqlCommand("Select OffenseTitle, OffenseCode From Offenses;")
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
Return dt
End Function
As the Form loads, set the properties of the ComboBox. DisplayMember matches the name of the title column and ValueMember is the name of the code column.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dt = GetOffenseData()
ComboBox1.DisplayMember = "OffenseTitle"
ComboBox1.ValueMember = "OffenseCode"
ComboBox1.DataSource = dt
End Sub
Then when the selected item in the combo changes, just set the .Text property of TextBox to the SelectedValue in the combo and your code appears.
Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
TextBox1.Text = ComboBox1.SelectedValue.ToString
End Sub
There are other ways to do this if your data source is other than a database. Please advise if you need additional help.
In addition to HardCode's comment and Mary's detailed answer, I can only add an answer that's somewhere in between them.
It might be the case, that the information is not taken from a database, but from another source, like a text/data file or a web service. So it might be useful to create an abstraction for the data source you actually use.
First, I create a class or struct that will hold the data for each combo box item.
Class Offense
Public ReadOnly Property Title As String
Public ReadOnly Property Code As String
Public Sub New(title As String, code As String)
Me.Title = title
Me.Code = code
End Sub
End Class
Next, you need a method that retrieves a list of offenses that you can bind to your combo box. It's entirely up to you how you fill/fetch the offenses list. I have simply hard coded your two values here.
Private Function GetOffenseData() As List(Of Offense)
Dim offenses As New List(Of Offense)
offenses.Add(New Offense("Kidnapping", "11-5-77"))
offenses.Add(New Offense("False Imprisonment", "11-5-78"))
Return offenses
End Function
At a certain moment (probably in your form's Load event handler), you need to initialize your combo box. Just like Mary did, I use data binding.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AWOffenseTitle.DropDownStyle = ComboBoxStyle.DropDownList
AWCN.ReadOnly = True
AWOffenseTitle.DisplayMember = NameOf(Offense.Title)
AWOffenseTitle.ValueMember = NameOf(Offense.Code)
AWOffenseTitle.DataSource = GetOffenseData()
End Sub
Note that I use the NameOf operator to get the desired property names of the Offense class. If you ever decide to rename the properties of your Offense class, you will be able to easily detect where they are used, since the compiler will complain if your code still uses the wrong property names somewhere.
Finally, the app needs to react to combo box value changes, so that the text box will show the corresponding offense code. Mary used an event handler for the SelectionChangeCommitted event, but I use a handler for the SelectedIndexChanged event instead:
Private Sub AWOffenseTitle_SelectedIndexChanged(sender As Object, e As EventArgs) Handles AWOffenseTitle.SelectedIndexChanged
AWCN.Text = AWOffenseTitle.SelectedValue
End Sub
(Up to now, I was not aware of the SelectionChangeCommitted event of the ComboBox control. I will need to look into this event to see if it is actually a better choice for this scenario, but I found that the SelectedIndexChanged event does the job just fine, so for now I sticked with that event, since I am more familiar with it.)

Simplify one-type syntaxis in vb.net

I have the next piece of code:
Private Sub TextBox_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged, TextBox2.TextChanged,
TextBox3.TextChanged, TextBox4.TextChanged, TextBox5.TextChanged, TextBox6.TextChanged, TextBox7.TextChanged,
TextBox8.TextChanged, TextBox9.TextChanged, TextBox10.TextChanged, TextBox13.TextChanged, TextBox14.TextChanged,
TextBox15.TextChanged, TextBox18.TextChanged, TextBox19.TextChanged, TextBox20.TextChanged
Double.TryParse(TextBox1.Text, Component.Methane.Mole)
Double.TryParse(TextBox2.Text, Component.Ethane.Mole)
Double.TryParse(TextBox3.Text, Component.Propane.Mole)
Double.TryParse(TextBox4.Text, Component.iButane.Mole)
Double.TryParse(TextBox5.Text, Component.nButane.Mole)
Double.TryParse(TextBox6.Text, Component.neoPentane.Mole)
Double.TryParse(TextBox7.Text, Component.nHexane.Mole)
Double.TryParse(TextBox8.Text, Component.nHeptane.Mole)
Double.TryParse(TextBox9.Text, Component.N2.Mole)
Double.TryParse(TextBox10.Text, Component.CO2.Mole)
Double.TryParse(TextBox13.Text, Component.iPentane.Mole)
Double.TryParse(TextBox14.Text, Component.nPentane.Mole)
Double.TryParse(TextBox15.Text, Compress.Avol)
Double.TryParse(TextBox18.Text, Compress.AF)
Double.TryParse(TextBox19.Text, Compress.AP)
Double.TryParse(TextBox20.Text, Compress.AT)
End Sub
Is there any possibility to make this procedure more compact, beatiful and smarter ? Use some kind of control, loop or something else? It would be greate to make it shorter and avoid typing. I am quite new in programming, any help is very appreciated!
Thanks in advance!
If your range of textboxes should only contain numbers, create a new Control that inherits from Textbox and alter the Textbox to only accept valid numbers. See an example here:
https://www.tigraine.at/2008/10/28/decimaltextbox-for-windows-forms/
The other thing I would point you is to look into Databinding. Databinding is something where a WinForm or WPF Control will "push" the value contained within the Control back to a property on an object. Windows has made a nice and quick write up on it here:
https://msdn.microsoft.com/en-us/library/2b4be09b.aspx
Finally, for "beautiful code" give things meaningful names. Currently your textbox have the default name and this can result in some very confusing problems later on in life. A quick and easy naming convention I follow is , for example, instead of "TextBox15" you could have TextboxCompressAvol (Or, txbxCompressAvol).

How can I check if a string given is a real word?

I am making a program that solves anagrams in Visual Basic. How can I check if a string given by the anagram solver is a real word? I know I will have to access some sort of dictionary but I have no idea how to do this?
I need a function that checks the word to return a true/false boolean value. Is this possible?
I'm using Visual Basic in Microsoft's VS2015.
Hunspell is pretty easy to use.
Install the .net-library through Nuget (open your project in Visual Studio, then > Extras > Nuget-Package-Manager -> Console, type Install-Package NHunspell)
Download the .aiff and .dic files, see the dictionaries link on the Hunspell project page. Include these files in your project or use absolute paths.
Sample Code:
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
Using h As New NHunspell.Hunspell(
"...path ...\en_US.aff",
"...path ...\en_US.dic")
Me.TextBox1.BackColor = If(h.Spell(Me.TextBox1.Text),
Color.PaleGreen, Color.PeachPuff)
End Using
End Sub
Hunspell
.net library NHunspell
NHunspell C# Code Samples
If your are using WPF then checking if a word in a textbox can be done simply by checking if it has a spelling error.
Public Function WordOk(Word As String) As Boolean
return TextBox1.GetNextSpellingErrorCharacterIndex(0, Windows.Documents.LogicalDirection.Forward) < 0
End Function
If you are using windows forms then you can create a "User Control (WPF)" to do the same thing, though it is a bit tricky to explain how to do that here.
(There may be a better test than the one I showed though.. I'm not overly familiar with WPF)

How do I pass Form1.TextBox1.Text to Form2.TextBox2.Text using Visual Basic (correctly)?

This is a continuation of a question asked two years ago in this thread:
VB6 equivalent of string.IsNullOrEmpty
(I think.) A programmer recommended I use the String.IsNullorEmpty method, which I used this thread for to convert to Visual Basic, but I still couldn't get it to work.
The specifics of my question are here, including all current code:
http://www.daniweb.com/software-development/visual-basic-4-5-6/threads/473930/passing-data-between-forms-in-vba
Here is the gist of it, copied directly from the second link:
So I'm trying to make a link between TextBox1.Text on Form1 to TextBox2.Text on Form 2. What I currently have is a line of code underneath my TextBox2_Change code reading:
TextBox2 = Form1.TextBox1.Text
This ALMOST does what I want it to do. The only problem is that it is requiring me to input any character in to the TextBox2 when Form2 pops up before it displays.
I'm trying to get that problem solved and then I'm eventually going to try to get it to chop off part of the file name until just the project file name displays.......but that's a whole different game I'll be playing. One step at a time.
Does anyone have any suggestions?
Explanation
You should write the code under the Form2_Load event.
If you write the code under Textbox2_TextChanged event, the code will be executed only when you type or delete something in Textbox2 (That is the same as Text being changed).
Code and Example
Private Sub Form2_Load () Handles Mybase.Load
Textbox2.Text = Form1.Textbox1.Text
End Sub
Hope it works perfectly!
The behaviour you observe is normal : your TextBox2 is only updated (with the value from TextBox1) ... when you update it manually (_Change).
Hey friend it very simple. you need not to add any kind of other functions just use dot(.) operator to access all components of Form1.
e.g.:
Form1.TextBox1.AppendText("hello")
or you can read value from Form2 and insert it into Form1.
e.g. :
Dim txt As String=TextBox1.Text
Form1.TextBox1.AppendText(txt)

Visual Basic (2010) - Using variables in embedded text files?

Ive always been able to just search for what I need on here, and I've usually found it fairly easily, but this seems to be an exception.
I'm writing a program in Visual Basic 2010 Express, it's a fairly simple text based adventure game.
I have a story, with multiple possible paths based on what button/option you choose.
The text of each story path is saved in its own embedded resource .txt file. I could just write the contents of the text files straight into VB, and that would solve my problem, but that's not the way I want to do this, because that would end up looking really messy.
My problem is that I need to use variable names within my story, here's an example of the contents of one of the embedded text files,
"When "+playername+" woke up, "+genderheshe+" didn't recognise "+genderhisher+" surroundings."
I have used the following code to read the file into my text box
Private Sub frmAdventure_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim thestorytext As String
Dim imageStream As Stream
Dim textStreamReader As StreamReader
Dim assembly As [Assembly]
assembly = [assembly].GetExecutingAssembly()
imageStream = assembly.GetManifestResourceStream("Catastrophe.CatastropheStoryStart.png")
textStreamReader = New StreamReader(assembly.GetManifestResourceStream("Catastrophe.CatastropheStoryStart.txt"))
thestorytext = textStreamReader.ReadLine()
txtAdventure.Text = thestorytext
End Sub
Which works to an extent, but displays it exactly as it is in the text file, keeps the quotes and the +s and the variable names instead of removing the quotes and the +s and replacing the variable names with what's stored within the variables.
Can anyone tell me what I need to change or add to make this work?
Thanks, and apologies if this has been answered somewhere and I just didn't recognise it as the solution or didn't know what to search to find it or something.
Since your application is compiled, you cannot just put some of your VB code in the text file and have it executed when it is read.
What you can do, and what is usually done, is that you leave certain tags inside your text file, then locate them and replace them with the actual values.
For example:
When %playername% woke up, %genderheshe% didn`t recognise %genderhisher% surroundings.
Then in your code, you would find all the tags:
Dim matches = Regex.Matches(thestorytext, "%(\w+?)%")
For Each match in matches
' the tag name is now in: match.Groups(1).Value
' replace the tag with the value and replace it back into the original string
Next
Of course the big problem still remains - which is how to fill in the actual values. Unfortunately, there is no clean way to do this, especially using any local variables.
You can either manually maintain a Dictionary of tag names and their values, or use Reflection to get the values directly at the runtime. While it should be used carefully (speed, security, ...), it will work just fine for your case.
Assuming you have all your variables defined as properties in the same class (Me) as the code that reads and processes this text, the code will look like this:
Dim matches = Regex.Matches(thestorytext, "%(\w+?)%")
For Each match in matches
Dim tag = match.Groups(1).Value
Dim value = Me.GetType().GetField(tag).GetValue(Me)
thestorytext = thestorytext.Replace(match.Value, value) ' Lazy code
Next
txtAdventure.Text = thestorytext
If you don't use properties, but only fields, change the line to this:
Dim value = Me.GetType().GetField(tag).GetValue(Me)
Note that this example is rough and the code will happily crash if the tags are misspelled or not existing (you should do some error checking), but it should get you started.