Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help me convert small VB code 1

Status
Not open for further replies.

Destruktion

Programmer
Mar 18, 2011
28
GB
Hi, I am trying to convert a small fun project from VB (I did not write the VB code, found it at this site:
Anyway this is what i got so far, it compiles and runs but I dont get the same output.

Original VB Code:

Code:
Dim selColor As Long

Private Sub cmbColors_Click()
selColor = CLng("&h" & cmbColors.Text)
picColor.BackColor = selColor
End Sub

Private Sub cmdClear_Click()
txtText.Text = ""
txtBBCode.Text = ""
End Sub

Private Sub cmdConvert_Click()
Dim x As Integer, sConverted As String, sLetter As String, cColor As Long
Dim Rev As Boolean

cColor = selColor

For x = 1 To Len(txtText.Text)
    sLetter = Mid(txtText.Text, x, 1)
    
    If Not sLetter = " " Then
        sConverted = sConverted & "[color=#" & Right("000000" & Hex(cColor), 6) & "]" & sLetter & "[/color]"
        
        If cColor = selColor + &HFF Then
            Rev = True
        End If
        If cColor = selColor Then
            Rev = False
        End If
        
        If Rev Then
            cColor = cColor - &H33
        Else
            cColor = cColor + &H33
        End If
    Else
        sConverted = sConverted & " "
    End If
Next
If chkBold.Value Then
    txtBBCode.Text = "[b]" & sConverted & "[/b]"
Else
    txtBBCode.Text = sConverted
End If

cmdCopy_Click
End Sub

Private Sub cmdCopy_Click()
Clipboard.Clear
Clipboard.SetText txtBBCode.Text
End Sub

Private Sub Form_Load()
cmbColors.ListIndex = 0
End Sub

My Delphi Code:

Code:
private
    function TextToGradientBBCode(sInput: String): String;

var
  SelColor: LongInt;

function Mid(Source: string; Start: integer; Length: integer): string;
begin
  Result := copy(Source,Start,Length);
end;

function Left(Source: string; Length: integer): string;
begin
  Result := copy(Source,1,Length);
end;

function Right(Source: string; Lengths: integer): string;
begin
  Result := copy(source,Length(Source) - Lengths,Lengths);
end;

function TForm1.TextToGradientBBCode(sInput: String): String;
var
  X: Integer;
  sConverted: String;
  sLetter: String;
  cColor: LongInt;
  Rev: Boolean;
begin
  Result:= '';

  cColor:= SelColor;

  for X:= 1 to Length(sInput) do
  begin
    sLetter:= Mid(sInput, X, 1);

    if sLetter <> ' ' then
    begin
      sConverted:= sConverted + '[color=#' + Right('000000' + IntToStr(cColor), 6) + ']' + sLetter + '[/color]';

      if cColor = SelColor + $FF then //TColor($FF) then
        Rev:= True;

      if cColor = SelColor then
        Rev:= False;

      if Rev then
        cColor:= cColor - $33 //TColor($33)
      else
        cColor:= cColor + $33 //TColor($33)
    end
    else
      sConverted:= sConverted + ' ';
  end;

  Result:= sConverted;
end;

procedure TForm1.cmdConvertClick(Sender: TObject);
begin
  SelColor:= clBlack; //TColor($000000);
  txtOutput.Lines.Text:= TextToGradientBBCode(txtInput.Lines.Text);
end;

I tried running my source with the exact same text as used in the link at the top: testing 123 testing, my output is different though.

Appreciate some help thanks.
 
A quick look without trying anything, show a couple of points.
Firstly most versions of Delphi have built in LeftStr and RightStr functions, so you dont need to write your own.

Next your VB code uses Hex() and you are using IntToStr() in Delphi, colour strings are in Hex in Delphi, but there Hex conversion routines in Delphi like IntToHex().

Actually you are defining your colour value as LongInt, Delphi has a built in type TColor. Look at using that.I think that's what the VB does.

Be careful that length() is returning what you want, might be a character out from the VB version.

What outputs do you get?




Steve: N.M.N.F.
If something is popular, it must be wrong: Mark Twain
 
Hi, thanks for the reply.

If you can see in my code i commented out TColor in several places as i tried it, and it worked but no difference.

I know about IntToHex already but i kept getting "There is no overloaded version of 'IntToHex' that can be called with these arguments" type errors.

The output code i was getting is like so:

Code:
[color=#000000]t[/color][color=#000005]e[/color][color=#000010]s[/color][color=#000015]t[/color][color=#000020]i[/color][color=#000025]n[/color][color=#000020]g[/color] [color=#000015]1[/color][color=#000010]2[/color][color=#000005]3[/color] [color=#000000]t[/color][color=#000005]e[/color][color=#000010]s[/color][color=#000015]t[/color][color=#000020]i[/color][color=#000025]n[/color][color=#000020]g[/color][color=#000015]
[/color][color=#000010]
[/color]

as you can the value for each color seems to increment by 5, ie #000005/#000010/#000015 etc.

You are most likely found out the problem with the mix ups of not calling correct hex values or something, so i need to include the integer to hex function somehow.

Thanks
 
Ok so I added StrUtils, i thought there would be delphi own string functions and funny enough i tried MidStr but it was unidentified.

Anyway, i managed to get IntToHex in there but the output has gone crazy.

It is a small code could you please fix it for me thanks!

here is latest attempt:

Code:
uses StrUtils;

private
    function TextToGradientBBCode(sInput: String): String;

var
  SelColor: TColor;

function TForm1.TextToGradientBBCode(sInput: String): String;
var
  X: Integer;
  sConverted: String;
  sLetter: String;
  cColor: TColor;
  Rev: Boolean;
begin
  Result:= '';

  cColor:= SelColor;

  for X:= 1 to Length(sInput) do
  begin
    (* ShowMessage(sInput[X]); // verify the length of text *)

    sLetter:= MidStr(sInput, X, 0);

    if sLetter <> ' ' then
    begin
      sConverted:= sConverted + '[color=#' + RightStr('000000' + IntToHex(cColor, 1), 6) + ']' + sLetter + '[/color]';

      if cColor = SelColor + TColor(IntToHex($FF, 1)) then
        Rev:= True;

      if cColor = SelColor then
        Rev:= False;

      if Rev then
        cColor:= cColor - TColor(IntToHex($33, 1))
      else
        cColor:= cColor + TColor(IntToHex($33, 1))
    end
    else
      sConverted:= sConverted + ' ';
  end;

  Result:= '[b]' + sConverted + '[/b]';
end;

procedure TForm1.cmdConvertClick(Sender: TObject);
begin
  SelColor:= TColor($000000);
  txtOutput.Lines.Text:= TextToGradientBBCode(txtInput.Lines.Text);
end;

and the output:

Code:
[b][color=#000000][/color][color=#5CA0E4][/color][color=#B941B0][/color][color=#15E4A4][/color][color=#728588][/color][color=#CF2654][/color][color=#2BC948][/color][color=#886A2C][/color][color=#E50AF8][/color][color=#41ADEC][/color][color=#9E4ED0][/color][color=#FAEF9C][/color][color=#579290][/color][color=#B43374][/color][color=#10D440][/color][color=#6D7734][/color][color=#CA1818][/color][color=#26B8E4][/color][color=#835BD8][/color][/b]

THanks!
 
Let us remember that this is a BBCode implementation and doesn't have anything to do with TColor. Note in the link that the output has three bytes in hex and not four.

That said, you have to think a little about what the code is doing when you look at other people's code, especially if you are looking to convert code from other languages. The conversion to Delphi presents a lot easier things than what the VB code shows. And maybe the VB code could be convoluted.

Code:
procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
  blue_color: byte;
  outstr: string;
  rev: boolean;
begin
  blue_color := $00;
  outstr := '';
  rev := false;
  for i := 1 to Length(Edit1.Text) do
    begin
      if Edit1.Text[i] = ' ' then
        outstr := outstr + ' '
      else
        begin
          outstr := outstr + '[color=#0000' + IntToHex(blue_color, 2) + ']' +
              Edit1.Text[i] + '[/color]';
          if blue_color = $FF then
            Rev := true
          else
          if blue_color = $00 then
            Rev := false;
          if Rev then
            blue_color := blue_color - $33
          else
            blue_color := blue_color + $33;
        end;
    end;
  memo1.lines.add(outstr);
end;

It is not possible for anyone to acknowledge truth when their salary depends on them not doing it.
 
Hi thanks Glen that works, but a few things..

<> how do you know the output was 3 bytes in hex and not four?
<> also noticed you dont use MidStr or RightStr in your code, is that just not needed because the original source is not well coded?

I always end up making code more complicated because I think too hard of solution when as you said yourself, delphi requires much less effort usually to do something. Instead of almost like for like copy/convert of the VB source I should of tried different approach like you did.

Thanks Glen
 
<> how do you know the output was 3 bytes in hex and not four?

A byte consists of eight bits which can be expressed in number systems of different ways. They are expressed in either binary, octal, decimal, or hexadecimal depending on need or usage. Typically, bytes are expressed in Hex or binary notation, because it enables you to see what the individual bits of the byte are set to.

Now, bytes are divided into the high and low sets (called nibble or half of an octet). If you look at the binary hex (base 16) representation of four bits, you'll see that each half is expressed as a digit from 0-F. So each byte is expressed by 2 digits in base 16. Your sample output had 6 digits so it's denoting three bytes.

<> also noticed you dont use MidStr or RightStr in your code, is that just not needed because the original source is not well coded?

It's been a while since I played with VB so I'm not sure if the VB code could have been done in a less confusing way. But if you look at the VB code, you'll see that it's picking up single characters, which can be done in Delphi just by indexing the string as I did.

delphi requires much less effort usually to do something.

Not always, sometimes it's much more effort depending on the language in question. I'm just saying I find by experience that it's usually good to understand what the code is looking to do and then let any conversion efforts be guided by that understanding as well as the original source.

This can often remove the "not well coded" aspect of the original source as well (and that happens to everybody's code at one time or another). I'm reminded of coming across a post once (with source!) of a person finding a production program where someone coded 100 lines of C++ code to (get ready) add 1 to a variable. The person that posted this guessed the person was just looking for job security so they made the code a mess so others would throw up their hands and leave it alone for them. Luckily for this place, this poster also noted that the person who coded this was no longer working there to create more of these messes.

It is not possible for anyone to acknowledge truth when their salary depends on them not doing it.
 
brilliant thanks Glen, cleared most of it up for me :)

100 lines to add 1? who was he trying to kid haha

Code:
var
  i: Integer
begin
  i:= 0;
  
  i:= i + 1;
end;

Thanks Glen, good job.
 
Actually, instead of

Code:
  i:= i + 1;

In Delphi, you could use

Code:
  inc(i);

This simply increments an integer by 1.

Also, what was "MidStr" in VB is "Copy" in Delphi. This is also in the StrUtils.

Code:
var
  BigString, SmallString: String;
begin
  BigString:= 'This is a big string.';
  SmallString:= Copy(BigString, 1, 4);
end;

SmallString would result in 'This'. I use Copy a lot with using Sockets in Delphi, as well as "Delete". I was hoping there was something like "Cut" as I always have to delete what I copy, but I couldn't find anything. So, I made this:

Code:
function CopyDel(S: String; Start, Length: Integer): String;
begin
  Result:= Copy(S, Start, Length);
  Delete(S, Start, Length);
end;

This comes in real handy when reading from a Buffer String, as I always need to delete what I copy.

There's another function "Pos" which returns the position of a substring within a string...

Code:
function GetNextPacket(var Buffer: String; Divider: String): String;
var
  P: Integer;
begin
  Result:= '';
  P:= Pos(Divider, Buffer);
  if P > 0 then begin
    Result:= Copy(Buffer, 1, P-1);
    Delete(Buffer, 1, P+(Length(Divider)-1));
  end;
end;

That function checks a large buffer string to see if a packet divider is found. The buffer can contain hundreds of packets, but I only need what's on the far left. If it doesn't find the Divider, it returns nothing, or else it copies everything before the divider and then removes what it copied, along with the divider.

That's just to give you a few more examples on string manipulation within Delphi. As for your particular project, I'm horrible with Bits, Bytes, and such.

Happy Coding!


JD Solutions
 
And adding on to the Copy example...

Code:
var
  BigString, SmallString: String;
begin
  BigString:= 'This is a big string.';
  SmallString:= Copy(BigString, 6, 2);
end;

This would result in just 'is'.

Code:
function Copy(const S: String; Index, Count: Integer): String;

- S - The larger string you want to copy from.
This could also be a Dynamic Array of some sort.
- Index - The starting position from where to copy.
The left-most position of a string is 1.
- Count - The number of characters to be copied.
Counts from 'Index' position.




JD Solutions
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top