Hi
I am trying to translate code from C# to Visual Cobol to allow numbered lists in a richtextbox on Windows Forms. This is to replicate a similar feature from a different application we are scrapping. The code I am having difficulty with is highlighted in red (same code highlighted in C# and Visual Cobol block), as I will explain.
We are using Visual Cobol 2.3 for Visual Stuidio Community 2015 on Windows 10.
The C# code is as follows:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing.Printing;
namespace RichTextBoxEx.Controls
{
public class RichTextBoxEx : RichTextBox
{
#region BULLETING
[StructLayout(LayoutKind.Sequential)]
private class PARAFORMAT2
{
public int cbSize;
public int dwMask;
public short wNumbering;
public short wReserved;
public int dxStartIndent;
public int dxRightIndent;
public int dxOffset;
public short wAlignment;
public short cTabCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
public int[] rgxTabs;
public int dySpaceBefore; // Vertical spacing before para
public int dySpaceAfter; // Vertical spacing after para
public int dyLineSpacing; // Line spacing depending on Rule
public short sStyle; // Style handle
public byte bLineSpacingRule; // Rule for line spacing (see tom.doc)
public byte bOutlineLevel; // Outline Level
public short wShadingWeight; // Shading in hundredths of a per cent
public short wShadingStyle; // Byte 0: style, nib 2: cfpat, 3: cbpat
public short wNumberingStart; // Starting value for numbering
public short wNumberingStyle; // Alignment, Roman/Arabic, (), ), ., etc.
public short wNumberingTab; // Space bet 1st indent and 1st-line text
public short wBorderSpace; // Border-text spaces (nbl/bdr in pts)
public short wBorderWidth; // Pen widths (nbl/bdr in half twips)
public short wBorders; // Border styles (nibble/border)
public PARAFORMAT2()
{
this.cbSize = Marshal.SizeOf(typeof(PARAFORMAT2));
}
}
#region PARAFORMAT MASK VALUES
// PARAFORMAT mask values
private const uint PFM_STARTINDENT = 0x00000001;
private const uint PFM_RIGHTINDENT = 0x00000002;
private const uint PFM_OFFSET = 0x00000004;
private const uint PFM_ALIGNMENT = 0x00000008;
private const uint PFM_TABSTOPS = 0x00000010;
private const uint PFM_NUMBERING = 0x00000020;
private const uint PFM_OFFSETINDENT = 0x80000000;
// PARAFORMAT 2.0 masks and effects
private const uint PFM_SPACEBEFORE = 0x00000040;
private const uint PFM_SPACEAFTER = 0x00000080;
private const uint PFM_LINESPACING = 0x00000100;
private const uint PFM_STYLE = 0x00000400;
private const uint PFM_BORDER = 0x00000800; // (*)
private const uint PFM_SHADING = 0x00001000; // (*)
private const uint PFM_NUMBERINGSTYLE = 0x00002000; // RE 3.0
private const uint PFM_NUMBERINGTAB = 0x00004000; // RE 3.0
private const uint PFM_NUMBERINGSTART = 0x00008000; // RE 3.0
private const uint PFM_RTLPARA = 0x00010000;
private const uint PFM_KEEP = 0x00020000; // (*)
private const uint PFM_KEEPNEXT = 0x00040000; // (*)
private const uint PFM_PAGEBREAKBEFORE = 0x00080000; // (*)
private const uint PFM_NOLINENUMBER = 0x00100000; // (*)
private const uint PFM_NOWIDOWCONTROL = 0x00200000; // (*)
private const uint PFM_DONOTHYPHEN = 0x00400000; // (*)
private const uint PFM_SIDEBYSIDE = 0x00800000; // (*)
private const uint PFM_TABLE = 0x40000000; // RE 3.0
private const uint PFM_TEXTWRAPPINGBREAK = 0x20000000; // RE 3.0
private const uint PFM_TABLEROWDELIMITER = 0x10000000; // RE 4.0
// The following three properties are read only
private const uint PFM_COLLAPSED = 0x01000000; // RE 3.0
private const uint PFM_OUTLINELEVEL = 0x02000000; // RE 3.0
private const uint PFM_BOX = 0x04000000; // RE 3.0
private const uint PFM_RESERVED2 = 0x08000000; // RE 4.0
public enum AdvRichTextBulletType
{
Normal = 1,
Number = 2,
LowerCaseLetter = 3,
UpperCaseLetter = 4,
LowerCaseRoman = 5,
UpperCaseRoman = 6
}
public enum AdvRichTextBulletStyle
{
RightParenthesis = 0x000,
DoubleParenthesis = 0x100,
Period = 0x200,
Plain = 0x300,
NoNumber = 0x400
}
#endregion
[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, [In, Out, MarshalAs(UnmanagedType.LPStruct)] PARAFORMAT2 lParam);
private AdvRichTextBulletType _BulletType = AdvRichTextBulletType.Number;
private AdvRichTextBulletStyle _BulletStyle = AdvRichTextBulletStyle.Period;
private short _BulletNumberStart = 1;
public AdvRichTextBulletType BulletType
{
get { return _BulletType; }
set
{
_BulletType = value;
NumberedBullet(true);
}
}
public AdvRichTextBulletStyle BulletStyle
{
get { return _BulletStyle; }
set
{
_BulletStyle = value;
NumberedBullet(true);
}
}
public void NumberedBullet(bool TurnOn)
{
PARAFORMAT2 paraformat1 = new PARAFORMAT2();
paraformat1.dwMask = (int)(PFM_NUMBERING | PFM_OFFSET | PFM_NUMBERINGSTART | PFM_NUMBERINGSTYLE | PFM_NUMBERINGTAB);
if (!TurnOn)
{
paraformat1.wNumbering = 0;
paraformat1.dxOffset = 0;
}
else
{
paraformat1.wNumbering = (short)_BulletType;
paraformat1.dxOffset = this.BulletIndent;
paraformat1.wNumberingStyle = (short)_BulletStyle;
paraformat1.wNumberingStart = _BulletNumberStart;
paraformat1.wNumberingTab = 500;
}
SendMessage(new System.Runtime.InteropServices.HandleRef(this, this.Handle), 0x447, 0, paraformat1);
}
#endregion
}
The C# to Cobol converter website did most of the work for me. After correcting some errors myself by adding the property clause to variables and renaming the number variable to numbered, I got as far as the following Visual Cobol code:
$set ilusing(System)
$set ilusing(System.Collections.Generic)
$set ilusing(System.ComponentModel)
$set ilusing(System.Data)
$set ilusing(System.Drawing)
$set ilusing(System.Text)
$set ilusing(System.Windows.Forms)
$set ilusing(System.Runtime.InteropServices)
$set ilusing(System.Drawing.Printing)
class-id RichTextBoxEx.Controls.RichTextBoxEx
inherits type RichTextBox.
$region PARAFORMAT MASK VALUES
*> PARAFORMAT mask values
01 PFM_STARTINDENT binary-long unsigned private constant value h"00000001".
01 PFM_RIGHTINDENT binary-long unsigned private constant value h"00000002".
01 PFM_OFFSET binary-long unsigned private constant value h"00000004".
01 PFM_ALIGNMENT binary-long unsigned private constant value h"00000008".
01 PFM_TABSTOPS binary-long unsigned private constant value h"00000010".
01 PFM_NUMBERING binary-long unsigned private constant value h"00000020".
01 PFM_OFFSETINDENT binary-long unsigned private constant value h"80000000" as binary-long unsigned.
*> PARAFORMAT 2.0 masks and effects
01 PFM_SPACEBEFORE binary-long unsigned private constant value h"00000040".
01 PFM_SPACEAFTER binary-long unsigned private constant value h"00000080".
01 PFM_LINESPACING binary-long unsigned private constant value h"00000100".
01 PFM_STYLE binary-long unsigned private constant value h"00000400".
01 PFM_BORDER binary-long unsigned private constant value h"00000800". *> (*)
01 PFM_SHADING binary-long unsigned private constant value h"00001000". *> (*)
01 PFM_NUMBERINGSTYLE binary-long unsigned private constant value h"00002000". *> RE 3.0
01 PFM_NUMBERINGTAB binary-long unsigned private constant value h"00004000". *> RE 3.0
01 PFM_NUMBERINGSTART binary-long unsigned private constant value h"00008000". *> RE 3.0
01 PFM_RTLPARA binary-long unsigned private constant value h"00010000".
01 PFM_KEEP binary-long unsigned private constant value h"00020000". *> (*)
01 PFM_KEEPNEXT binary-long unsigned private constant value h"00040000". *> (*)
01 PFM_PAGEBREAKBEFORE binary-long unsigned private constant value h"00080000". *> (*)
01 PFM_NOLINENUMBER binary-long unsigned private constant value h"00100000". *> (*)
01 PFM_NOWIDOWCONTROL binary-long unsigned private constant value h"00200000". *> (*)
01 PFM_DONOTHYPHEN binary-long unsigned private constant value h"00400000". *> (*)
01 PFM_SIDEBYSIDE binary-long unsigned private constant value h"00800000". *> (*)
01 PFM_TABLE binary-long unsigned private constant value h"40000000". *> RE 3.0
01 PFM_TEXTWRAPPINGBREAK binary-long unsigned private constant value h"20000000". *> RE 3.0
01 PFM_TABLEROWDELIMITER binary-long unsigned private constant value h"10000000". *> RE 4.0
*> The following three properties are read only
01 PFM_COLLAPSED binary-long unsigned private constant value h"01000000". *> RE 3.0
01 PFM_OUTLINELEVEL binary-long unsigned private constant value h"02000000". *> RE 3.0
01 PFM_BOX binary-long unsigned private constant value h"04000000". *> RE 3.0
01 PFM_RESERVED2 binary-long unsigned private constant value h"08000000". *> RE 4.0
01 _BulletType type AdvRichTextBulletType private value type AdvRichTextBulletType::Numbered.
01 _BulletStyle type AdvRichTextBulletStyle private value type AdvRichTextBulletStyle::Period.
01 _BulletNumberStart binary-short private value 1.
$end-region
method-id SendMessage (hWnd as type HandleRef, msg as binary-long, wParam as binary-long, lParam as type PARAFORMAT2 attribute In attribute Out attribute MarshalAs(type UnmanagedType::LPStruct)) returning return-value as type IntPtr
attribute DllImport("user32.dll", prop CharSet = type System.Runtime.InteropServices.CharSet::Auto) private static extern
attribute DllImport("user32.dll", prop CharSet = type System.Runtime.InteropServices.CharSet::Auto).
end method.
property-id BulletType type AdvRichTextBulletType final.
getter.
set property-value to _BulletType
setter.
set _BulletType to property-value
invoke NumberedBullet(true)
end property.
property-id BulletStyle type AdvRichTextBulletStyle final.
getter.
set property-value to _BulletStyle
setter.
set _BulletStyle to property-value
invoke NumberedBullet(true)
end property.
method-id NumberedBullet (TurnOn as condition-value) final.
declare paraformat1 as type PARAFORMAT2 = new PARAFORMAT2()
set paraformat1::dwMask to (PFM_NUMBERING b-or PFM_OFFSET b-or PFM_NUMBERINGSTART b-or PFM_NUMBERINGSTYLE b-or PFM_NUMBERINGTAB) as binary-long
if not TurnOn
set paraformat1::wNumbering to 0
set paraformat1::dxOffset to 0
else
set paraformat1::wNumbering to _BulletType as binary-short
set paraformat1::dxOffset to self::BulletIndent
set paraformat1::wNumberingStyle to _BulletStyle as binary-short
set paraformat1::wNumberingStart to _BulletNumberStart
set paraformat1::wNumberingTab to 500
end-if
invoke SendMessage(new System.Runtime.InteropServices.HandleRef(self, self::Handle), h"447", 0, paraformat1)
end method.
$region BULLETING
class-id PARAFORMAT2 private
attribute StructLayout(type LayoutKind::Sequential).
01 cbSize binary-long property.
01 dwMask binary-long property.
01 wNumbering binary-short property.
01 wReserved binary-short property.
01 dxStartIndent binary-long property.
01 dxRightIndent binary-long property.
01 dxOffset binary-long property.
01 wAlignment binary-short property.
01 cTabCount binary-short property.
01 rgxTabs binary-long occurs any property.
01 dySpaceBefore binary-long property. *> Vertical spacing before para
01 dySpaceAfter binary-long property. *> Vertical spacing after para
01 dyLineSpacing binary-long property. *> Line spacing depending on Rule
01 sStyle binary-short property. *> Style handle
01 bLineSpacingRule binary-char unsigned property. *> Rule for line spacing (see tom.doc)
01 bOutlineLevel binary-char unsigned property. *> Outline Level
01 wShadingWeight binary-short property. *> Shading in hundredths of a per cent
01 wShadingStyle binary-short property. *> Byte 0: style, nib 2: cfpat, 3: cbpat
01 wNumberingStart binary-short property. *> Starting value for numbering
01 wNumberingStyle binary-short property. *> Alignment, Roman/Arabic, (), ), ., etc.
01 wNumberingTab binary-short property. *> Space bet 1st indent and 1st-line text
01 wBorderSpace binary-short property. *> Border-text spaces (nbl/bdr in pts)
01 wBorderWidth binary-short property. *> Pen widths (nbl/bdr in half twips)
01 wBorders binary-short property. *> Border styles (nibble/border)
method-id new.
set self::cbSize to type Marshal::SizeOf(type of PARAFORMAT2)
end method.
end class.
enum-id AdvRichTextBulletType.
78 Normal value 1.
78 Numbered value 2.
78 LowerCaseLetter value 3.
78 UpperCaseLetter value 4.
78 LowerCaseRoman value 5.
78 UpperCaseRoman value 6.
end enum.
enum-id AdvRichTextBulletStyle.
78 RightParenthesis value h"000".
78 DoubleParenthesis value h"100".
78 Period value h"200".
78 Plain value h"300".
78 NoNumber value h"400".
end enum.
$end-region
end class.
The code blocks are quite long, apologies for that. I tried dragging the program files into the editor but it did not work!
The part I am hving difficulty with is the code highlighted in red.
I am getting two errors on the line
attribute DllImport("user32.dll", prop CharSet = type System.Runtime.InteropServices.CharSet::Auto) private static extern
Error COBCH0937 : Attribute 'System.Runtime.InteropServices.DllImportAttribute' not allowed in this context on the line
Error COBCH0071 : PROCEDURE DIVISION missing or unknown statement
If I change the word extern to external it makes no difference to the second error.
I notice when I debug the C# the code in red is never executed.
The nested classes in the C# code are confusing also, I have never used these in VC.
Any help most appreciated.
Kind Regards
Brendan
#C
#Richtextbox
#c
#VisualCOBOL
