Using Objective Grid in a WinForm
One straightforward way to integrate MFC-based projects with .NET libraries is to set the /clr compiler option and use C++/CLI. Stingray Objective Grid samples are provided with a /clr build configuration to demonstrate compatibility with this approach.
This section discusses two possible ways for integrating Objective Grid into a WinForm:
*Use C++/CLI projects to employ Windows Forms and apply CGXGridWnd-based classes directly.
*Create .NET controls wrapping classes from Objective Grid libraries and use these controls with any .NET language, particularly C#, VB, C++/CLI.
Simple samples that demonstrate these approaches are shipped with Stingray Studio:
*<install_dir>\Samples\Grid\Integration with .NET\GridForm
*<install_dir>\Samples\Grid\Integration with .NET\GridControl
More advanced samples are available in the Perforce Knowledge Base https://rwkbp.makekb.com/). Specifically, see Using Objective Grid with C++/CLI at https://rwkbp.makekb.com//index.php?View=entry&EntryID=1400.
The procedures below reference “Using the Objective Grid Static Libraries” in this chapter for more detailed information on how to perform particular steps.
Direct Use of Objective Grid in a WinForm
To embed a grid in a WinForm:
1. Use the Visual Studio App Wizard to create a Visual C++\CLR\Windows Form Application project GridForm.
2. Add grid resources, as described in Step 2 of “Using the Objective Grid Static Libraries”.
3. Add #include to the stdafx.h file, as described in Step 4 of “Using the Objective Grid Static Libraries”.
4. Add GXInit() to the InitInstance() method, as described in Step 5 of “Using the Objective Grid Static Libraries”.
5. Add the following immediately after class CmyApp (to initialize grid libraries):
 
CMyApp theApp;
6. Add a member to class Form1:
 
private: CGXGridWnd *m_pGX;
7. Initialize the grid, using this code:
 
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
m_pGX = new CGXGridWnd();
if (!m_pGX) return;
DWORD dwFlags = WS_TABSTOP | WS_BORDER
| WS_VISIBLE | WS_VSCROLL | WS_HSCROLL;
 
CRect rect(panel1->ClientRectangle.Left,
panel1->ClientRectangle.Top,
panel1->ClientRectangle.Right,
panel1->ClientRectangle.Bottom);
 
BOOL bOk = m_pGX->Create(dwFlags, rect,
CWnd::FromHandle((HWND)panel1->Handle.ToInt32()), 32000);
 
m_pGX->Initialize();
 
m_pGX->GetParam()->SetSortRowsOnDblClk(TRUE);
m_pGX->GetParam()->EnableMoveCols(TRUE);
m_pGX->GetParam()->EnableMoveRows(TRUE);
m_pGX->GetParam()->EnableSelection(TRUE);
 
m_pGX->LockUpdate(TRUE);
m_pGX->SetRowCount(15);
m_pGX->SetColCount(5);
m_pGX->SetStyleRange(CGXRange(1,1),
CGXStyle().SetControl(GX_IDS_CTRL_PUSHBTN));
m_pGX->LockUpdate(FALSE);
}
8. Clean up memory in the destructor:
 
~Form1()
{
if(m_pGX)
delete m_pGX;
if (components)
{
delete components;
}
}
 
9. Optionally, add _GXDLL to the Preprocessor definitions, as described in Step 4 of “Converting an Application to Use the Objective Grid Extension DLL”.
10. Build and run the project.
Use of Objective Grid in a .NET Control
To embed a grid in a WinForm:
1. Use the Visual Studio App Wizard to create a Visual C++\CLR\Windows Form Control Library project Grid.
2. Add grid resources, as described in Step 2 of “Using the Objective Grid Static Libraries”.
3. Add #include to the stdafx.h file, as described in Step 4 of “Using the Objective Grid Static Libraries”.
4. Add the following immediately after namespace Grid {…}:
 
CMyApp theApp;
5. Add this member to class GridControl:
private: CGXGridWnd *m_pGX;
6. Iinitialize the grid, using this code:
 
private: System::Void GridControl_Load(System::Object^ sender,
System::EventArgs^ e)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
GXInit();
m_pGX = new CGXGridWnd();
if (!m_pGX) return;
DWORD dwFlags = WS_TABSTOP | WS_BORDER
| WS_VISIBLE | WS_VSCROLL | WS_HSCROLL;
CRect rect(ClientRectangle.Left, ClientRectangle.Top,
ClientRectangle.Right,ClientRectangle.Bottom);
 
BOOL bOk = m_pGX->Create(dwFlags,rect,
CWnd::FromHandle((HWND)this->Handle.ToInt32()),32000);
 
m_pGX->Initialize();
 
m_pGX->GetParam()->SetSortRowsOnDblClk(TRUE);
m_pGX->GetParam()->EnableMoveCols(TRUE);
m_pGX->GetParam()->EnableMoveRows(TRUE);
m_pGX->GetParam()->EnableSelection(TRUE);
 
m_pGX->LockUpdate(TRUE);
m_pGX->SetRowCount(15);
m_pGX->SetColCount(5);
m_pGX->LockUpdate(FALSE);
}
7. Expose the APIs to call from the parent program:
 
public: System::Void SetValueRange(int t, int l, int b, int r,
String^ value)
{
m_pGX->SetValueRange(CGXRange(t, l, b, r), value);
}
public: System::Void SetControl(int t, int l, int b, int r, WORD
nControl)
{
m_pGX->SetStyleRange(CGXRange(t, l, b, r),
CGXStyle().SetControl(nControl));
}
8. Clean up memory, as described in Step 8 of “Direct Use of Objective Grid in a WinForm”.
9. Build the control.
10. Add a new project to the solution in any .NET language program; here, we’ll use Other Languages |Visual C# |Windows Forms Application.
11. Open Form1.
12. Select Tools | Choose Toolbox Items, then click Browse. Navigate to and select Grid.dll built in Step 9.
For x64 Build Configurations:
For x64 build configurations (or “AnyCPU” on an x64 machine), any control built with /clr (or even /clr:pure) throws an error when you try to add it to the Toolbox; controls built only with /clr:safe are valid for the Toolbox. This is a current Visual Studio limitation. As a workaround, you can use a control built with x64 and /clr by adding code to WinForms manually, rather then using the Toolbox.
To do so, set the configuration to Win32, use the Toolbox to add the control built with Win32, and then set the x64 build configuration and build it. The reference should be set to the GridControl project, rather then to a particular assembly.
Alternatively, save the Windows Forms Designer generated code and use it for initialization of an x64 control in a project with an x64 build configuration, like so:
 
// Add a member to class Form1
private Grid.GridControl gridControl1;
// Use following code to initialize the control
this.gridControl1 = new Grid.GridControl();
this.gridControl1.Location = new System.Drawing.Point(77, 57);
this.gridControl1.Name = "gridControl1";
this.gridControl1.Size = new System.Drawing.Size(350, 235);
this.gridControl1.TabIndex = 0;
13. Add a reference to the Grid project in the Windows Forms Application.
14. Initialize GridControl with the following code:
 
private void Form1_Load(object sender, EventArgs e)
{
this.gridControl1.SetValueRange(1, 1, 1, 1, "Value");
this.gridControl1.SetControl(2, 1, 2, 1,
GX_IDS_CTRL_PUSHBTN);
}
To use an embedded pushbutton, you can add the following to class Form1:
 
private ushort GX_IDS_CTRL_PUSHBTN = 52514;
15. Build and run the solution.