Skip to main content

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

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

Try the following:

method-id SendMessage static private attribute DllImport("user32.dll", prop CharSet = type System.Runtime.InteropServices.CharSet::Auto).
procedure division using 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.


Try the following:

method-id SendMessage static private attribute DllImport("user32.dll", prop CharSet = type System.Runtime.InteropServices.CharSet::Auto).
procedure division using 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.

Hi

That worked to a point.  The syntax errors disappeared and I was able to build the project.  I then created a UserControl (called it usrc-notes) with a tollstrip and this RichTextBox (called it RichTextBoxJP) in the same project called it USRCS), and added this to a Form (called it FRM-RTBJP) for testing.  However, I then got other issues.

Before I add the UserControl to the Form, I was unable to add usrc-notes to the toolbox when I went to Choose Items.. and selected the .dll, RichTextBoxJP was available but not usrc-notes.  I got around this by adding USRCS to the same solution as FRM-RTBJP)

I was then not able to debug into the class RichTextBoxJP.  I got around this by building USRCS in its own solution and adding breakpoints, and then building FRM-RTBJP in its own solution.

When testing I got an error on line

invoke SendMessage(new System.Runtime.InteropServices.HandleRef(self, self::Handle), h"447", 0, paraformat1)

Cannot marshal 'parameter #1': HandleRefs cannot be marshaled ByRef or from unmanaged to managed.

So I changed the line

procedure division using 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.

to

procedure division using by value hWnd as type HandleRef, by reference 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.

After that change the app ran with no errors but the line

invoke SendMessage(new System.Runtime.InteropServices.HandleRef(self, self::Handle), h"447", 0, paraformat1)

did not work.  The paragraph format remained the same, I was looking for a numbered list paragraph.  I checked the return value and it was zero, it should return non-zero if the invoke worked.

I tried a few other fixes, adding references, etc, but nothing worked.

Again, any help appreciated.

Thank you

Brendan


Hi

That worked to a point.  The syntax errors disappeared and I was able to build the project.  I then created a UserControl (called it usrc-notes) with a tollstrip and this RichTextBox (called it RichTextBoxJP) in the same project called it USRCS), and added this to a Form (called it FRM-RTBJP) for testing.  However, I then got other issues.

Before I add the UserControl to the Form, I was unable to add usrc-notes to the toolbox when I went to Choose Items.. and selected the .dll, RichTextBoxJP was available but not usrc-notes.  I got around this by adding USRCS to the same solution as FRM-RTBJP)

I was then not able to debug into the class RichTextBoxJP.  I got around this by building USRCS in its own solution and adding breakpoints, and then building FRM-RTBJP in its own solution.

When testing I got an error on line

invoke SendMessage(new System.Runtime.InteropServices.HandleRef(self, self::Handle), h"447", 0, paraformat1)

Cannot marshal 'parameter #1': HandleRefs cannot be marshaled ByRef or from unmanaged to managed.

So I changed the line

procedure division using 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.

to

procedure division using by value hWnd as type HandleRef, by reference 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.

After that change the app ran with no errors but the line

invoke SendMessage(new System.Runtime.InteropServices.HandleRef(self, self::Handle), h"447", 0, paraformat1)

did not work.  The paragraph format remained the same, I was looking for a numbered list paragraph.  I checked the return value and it was zero, it should return non-zero if the invoke worked.

I tried a few other fixes, adding references, etc, but nothing worked.

Again, any help appreciated.

Thank you

Brendan

Does this work correctly if you use the C# version of the RichTextBox within the UserControl instead of the COBOL version?


Does this work correctly if you use the C# version of the RichTextBox within the UserControl instead of the COBOL version?

Hi Chris

The C# version was on a Form rather than a UserControl, but the numbered lists option did work.

Brendan


Hi Chris

The C# version was on a Form rather than a UserControl, but the numbered lists option did work.

Brendan

I got the COBOL version to work in a User Control. I created one C# version and one COBOL version and used them on the same form. I tested with Visual COBOL 7.0.

The problem was how one of the fields was defined in the PARAFORMAT2 structure,

The rgxTabs field was being defined without the MarshalAs attribute so the structure was the incorrect length.

It should be defined as:

01 rgxTabs binary-long occurs any
     attribute MarshalAs(type UnmanagedType::ByValArray , property SizeConst = h"20").

Also SendMessage should be defined as:

method-id SendMessage static private attribute DllImport("user32.dll", prop CharSet = type System.Runtime.InteropServices.CharSet::Auto).

procedure division using by value 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.
end method.