Implementing Unicode Characters into VB Console Application - vb.net

I'm trying to create a Backgammon game board using Unicode graphics with an array back-end. For example; White Draughts Man: U+26C0 to represent checkers on a slot. What do I need to do to make this work ?
I've tried using ChrW() with the Unicode that is given from a Unicode table elsewhere
PS: This code is from a test application before adding to my actual assignment.
I just receive an error.
Sub Main()
Console.OutputEncoding = System.Text.Encoding.Unicode
Console.WriteLine(ChrW(&H26C0))
Console.ReadKey()
End Sub

Related

VB 2010: Console application prints some superscript number characters as normal

I just have a small issue with a Visual Basic (2010 Express) .NET application I'm making. It's a console-based application and I want it to print superscript numbers.
Well, I've found out the superscript numbers from Charmap and my code is this:
Public Module MainModule
Public Sub Main()
Console.Write(GetExponentialNumAsStr(12345, 12345)) 'This must be printed as 12345¹²³⁴⁵
Console.ReadKey(True)
End Sub
Public Function GetExponentialNumAsStr$(Number As Double, Exponent%)
If Exponent = 1 Then Return Number : Exit Function
Return Number.ToString & Exponent.ToString.Replace("-", "⁻").Replace("0", "⁰").Replace("1", "¹").Replace("2", "²").Replace("3", "³").Replace("4", "⁴").Replace("5", "⁵").Replace("6", "⁶").Replace("7", "⁷").Replace("8", "⁸").Replace("9", "⁹")
End Function
End Module
Okay, the GetExponentialNumAsString$ function works well and gives 12345¹²³⁴⁵, which is okay (checked through Immediate window), but the only problem is that while printing the same in the Console view gives this:
123451²345
Why is it that only 2 is shown in superscript form and why not the other digits also?
If I try printing 0 to 9 as superscript, it comes like this:
1²345678?°
Well 9 is gone, but the other digits is what confusing me. Only 2 and 0 are shown in superscript form!
I also tried copy-pasting all the superscript numbers in a Command Prompt window... this is what came:
Command Prompt, in fact, when copy-pasted, shows correctly!
So what should I do? Convert those superscript numbers to CP-437 (DOS) encoding and then display it?
Please help me! Thank you everybody!
EDIT: I've tried saving that thing as a file in my Desktop using CP-437 encoding. What appears is like 1ý345678?ø. And when converted back manually to UTF-8 or one of the general encodings, it comes back as 1²345678?°.
Also tried using ECHO ¹²³⁴⁵⁶⁷⁸⁹⁰>Hello123.TXT and what came was the same thing as above. So... has no use.
And I am a bit sure that CP-437 has those superscript characters because Command Prompt can display them!!!
Thanks to Hans Passant's comment, the trick is to set the Console's output encoding to UTF-8, such as
Console.OutputEncoding = System.Text.Encoding.UTF8
And look! It comes!

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.

String length with embeded null in vb.net

I have a simple question: How vb.net determine string length and treat string's termination?
I know in C (and its family) null character is end of string. In vb6 null character has no effect on string's termination but in vb.net it seems to be foggy!
Assume this code in vb6:
Private Sub Command1_Click()
Dim Str As String
Str = "Death is a good user," & Chr(0) & " Yes I'm good"
RichTextBox1.Text = Str
RichTextBox1.Text = RichTextBox1.Text & vbNewLine & Len(Str)
End Sub
This what happens when this code runs:
And it's alright. This is similar code in C:
#include "stdafx.h"
#include <string.h>
int main(int argc, char* argv[])
{
char *p="Death is a good user,\0 Yes I'm good";
printf("String:%s\nString length:%d\n",p,strlen(p));
return 0;
}
And this is what happens:
Which is fine too according C rules, but here is the same code in vb.net:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim str As String = "Death is a good user," & Chr(0) & " Yes I'm good"
RichTextBox1.Text = str
RichTextBox1.Text &= vbNewLine & str.Length
End Sub
And what happens:
Which doesn't seems about right!
Edit 1: Writing to file seems to be right:
Edit 2: Mark and tcarvin suggest, it may be UI's problem but it doesn't explain why vb6 shows whole string!
Edit 3: I know Windows and its API,UI,... are written in C, So it would be normal for them to react like C, but as I showed above, they don't.
In VB.NET (and C#) strings are treated very similarly to how they are in VB6, and that is they have an explicit length that is not based on any particular character or characters contained within them.
In regards to the RichTextBox, it would simply appear that it does not support an embedded null character.
There are 3 distinct string types used in your snippets by the underlying runtime support libraries:
BSTR, used by VB6. It is an COM Automation type used by all ActiveX controls that can store a Unicode string and includes an explicit length. BSTR can therefore store embedded zeros.
C strings, used by the C language. No explicit length is stored, a zero indicates end-of-string. The winapi is C based and uses C strings in its functions.
System.String, the .NET string type and used in any .NET code. Similar to a BSTR, it also has an explicit length field and can thus store strings with embedded zeros.
In all three cases interop needs to be used by the underlying runtime support libraries to make the string visible:
VB6 uses an ActiveX control for the RichEditBox. Exactly what the control looks like is hard to guess, it is pretty specific to VB6 and is named richtx32.ocx. It does use the native Windows richedit control as well (riched32.dll) so the ActiveX control very much acts as a wrapper to make the native Windows control usable in a VB6 app. You've conclusively demonstrated that it honors the behavior of a BSTR and handles embedded zeros, like any ActiveX control should.
The C program uses the C Runtime Library which in turn implements printf() by calling a winapi console function, WriteConsole(). This api function is C based but the buck already stopped at printf(), an embedded zero is a string terminator for that function. No surprises here.
The Winforms program uses the .NET RichEditBox class, a managed wrapper for the riched20.dll native Windows control. The underlying mechanism is pinvoke, almost all properties and methods of the class are implemented by pinvoking SendMessage() to send messages like EM_SETTEXTEX, the message that alters the text displayed by the control. This is also a C based api, a zero acts like a string terminator. Unlike the richtx32.ocx wrapper, the .NET RichEditBox wrapper class does not make an effort to properly handle strings with embedded zeros. It simply passes the string as-is and leaves it up to the pinvoke marshaller to convert the .NET string to a C string. Which has no other option than to truncate the string at the zero since C strings don't have a length field.

VB seems to lose newlines when called over COM

I have a VB method
Public Sub append_text(ByVal s As String)
f1.TextBox1.AppendText(s)
End Sub
which is called over COM from C++
_bstr_t b(L"test\nnew\nlines\n");
ATLENSURE_SUCCEEDED(t->append_text(b));
But the text box ends up saying
testnewlines
Without the aforementioned new lines.
Why is that then?
For the sake of completeness, posting my comment as an answer (now that I know it's correct...):
Different operating systems consider different character combinations as new lines. The *nixes, for instance, use a single \n, as in your code. Windows, on the other hand, uses the \r\n combination. Therefore, the single \n in your string just isn't enough to be considered a new line marker. Using \r\n will do the trick.
Eran is right.
To fix it on the VB side, try this
Dim s2 As String = s.Replace(vbLf, vbCrLf)
f1.TextBox1.AppendText(s2)
EDIT Sideshow Bob has compiled and tested this.

Is there any way to align text in message box in vb or vba?

Is there any way to align text into the center in msgbox in VB or VBA? Does VB have any functionality to do the same?
No. The MsgBox() function is simply a wrapper for the Windows MessageBox() function and as such has no stylistic control over the dialog beyond the icon.
If you want to change it any further than this, you will need to create your own window and show that instead.
On Windows Vista+ you can use TaskDialogs that allow a lot more control.
no, but you can cheat by using spaces.
msgbox(" your message")
VBA
Some notes: http://access.mvps.org/access/bugs/bugs0035.htm AND http://www.tek-tips.com/viewthread.cfm?qid=435428 However, it is not so difficult to build your own message box, which solves all your problems.
When you are building your strings you could pad them at the beginning and end with spaces to achieve a target length. If you're using excel the worksheet function rept is handy for this.
function pad_n_center(byval mystring as string, lenmax as integer) as string
dim pad_by as integer
dim pad as string
pad_by = (lenmax - len(mystring))/2
'some more code to finesse that?
pad = worksheetfunction.rept(" ",pad_by)
pad_n_center = pad & mystring & pad
end function
As mentioned before if the msgbox still doesn't look good you can use textbox shape object (or other objects) to get the desired effect.