Test for the Microsoft Flex Grid Control:
' ########################################################################################
' Microsoft Windows
' Contents: Embedded Microsoft Flex Grid Control
' Compiler: FreeBasic 32 & 64 bit
' Copyright (c) 2017 Jose Roca. Freeware. Use at your own risk.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
#define UNICODE
#INCLUDE ONCE "Afx/AfxCOM.inc"
#INCLUDE ONCE "Afx/CAxHost/CAxHost.inc"
#INCLUDE ONCE "Afx/CDispInvoke.inc"
#INCLUDE ONCE "Afx/CADODB/CADODB.inc"
USING Afx
DECLARE FUNCTION WinMain (BYVAL hInstance AS HINSTANCE, _
BYVAL hPrevInstance AS HINSTANCE, _
BYVAL szCmdLine AS ZSTRING PTR, _
BYVAL nCmdShow AS LONG) AS LONG
END WinMain(GetModuleHandleW(NULL), NULL, COMMAND(), SW_NORMAL)
DECLARE FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT
CONST IDC_GRID = 1001
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS HINSTANCE, _
BYVAL hPrevInstance AS HINSTANCE, _
BYVAL szCmdLine AS ZSTRING PTR, _
BYVAL nCmdShow AS LONG) AS LONG
' // Set process DPI aware
' // The recommended way is to use a manifest file
AfxSetProcessDPIAware
' // Creates the main window
DIM pWindow AS CWindow
' -or- DIM pWindow AS CWindow = "MyClassName" (use the name that you wish)
DIM hwndMain AS HWND = pWindow.Create(NULL, "Microsoft Flex Grid", @WndProc)
' // Sizes it by setting the wanted width and height of its client area
pWindow.SetClientSize(800, 450)
' // Centers the window
pWindow.Center
DIM wszLibName AS WSTRING * 260 = ExePath & "\Msflxgrd.ocx"
DIM CLSID_MSFlexGrid AS CLSID = (&h6262D3A0, &h531B, &h11CF, {&h91, &hF6, &hC2, &h86, &h3C, &h38, &h5E, &h30})
DIM IID_IMSFlexGrid AS IID = (&h5F4DF280, &h531B, &h11CF, {&h91, &hF6, &hC2, &h86, &h3C, &h38, &h5E, &h30})
DIM RTLKEY_MSFlexGrid AS WSTRING * 260 = "72E67120-5959-11cf-91F6-C2863C385E30"
DIM pHost AS CAxHost = CAxHost(@pWindow, IDC_GRID, wszLibName, CLSID_MSFlexGrid, _
IID_IMSFlexGrid, RTLKEY_MSFlexGrid, 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
SetFocus pHost.hWindow
' Open an ADO connection
DIM pConnection AS CAdoConnection PTR = NEW CAdoConnection
pConnection->ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ExePath & $"\nwind.mdb"
pConnection->Open
' Open a recordset
DIM pRecordset AS CAdoRecordset PTR = NEW CAdoRecordset
DIM cvSource AS CVAR = "SELECT * FROM Customers"
pRecordset->Open(cvSource, pConnection, adOpenKeyset, adLockOptimistic, adCmdText)
' Move to the last record
pRecordset->MoveLast
' Set the number of grid rows and columns
DIM pGrid AS CDispInvoke = pHost.OcxDispObj
pGrid.Put("Rows") = pRecordset->RecordCount + 1
pGrid.Put("Cols") = 12
' Set the headers
pGrid.Set("TextMatrix", 0, 1, "Customer ID")
pGrid.Set("TextMatrix", 0, 2, "Company Name")
pGrid.Set("TextMatrix", 0, 3, "Contact Name")
pGrid.Set("TextMatrix", 0, 4, "Contact Title")
pGrid.Set("TextMatrix", 0, 5, "Address")
pGrid.Set("TextMatrix", 0, 6, "City")
pGrid.Set("TextMatrix", 0, 7, "Region")
pGrid.Set("TextMatrix", 0, 8, "Postal Code")
pGrid.Set("TextMatrix", 0, 9, "Country")
pGrid.Set("TextMatrix", 0, 10, "Phone")
pGrid.Set("TextMatrix", 0, 11, "Fax")
' Change the width of the columns (measures are in twips)
pGrid.Set("ColWidth", 0, 300)
pGrid.Set("ColWidth", 1, 1100)
pGrid.Set("ColWidth", 2, 3000)
pGrid.Set("ColWidth", 3, 2000)
pGrid.Set("ColWidth", 4, 2000)
pGrid.Set("ColWidth", 5, 3000)
pGrid.Set("ColWidth", 6, 1500)
pGrid.Set("ColWidth", 7, 700)
pGrid.Set("ColWidth", 8, 1200)
pGrid.Set("ColWidth", 9, 1200)
pGrid.Set("ColWidth", 10, 1500)
pGrid.Set("ColWidth", 11, 1500)
' Allow to resize columns
pGrid.Put("AllowUserResizing") = 1 ' flexResizeColumns
' Change the foreground and background colors
pGrid.Put("ForeColor") = BGR(0, 0, 0)
pGrid.Put("BackColor") = BGR(255,255,235)
' Move to the first record
pRecordset->MoveFirst
' Parse the recordset and fill the grid
DIM row AS LONG = 1
WHILE NOT pRecordset->EOF
'Select the row
pGrid.Put("Row") = row
' Set the content of cell 1
pGrid.Put("Col") = 1
pGrid.Put("CellAlignment") = 1 ' flexAlignLeftCenter
pGrid.Put("Text") = pRecordset->Collect("CustomerID")
' Set the content of cell 2
pGrid.Put("Col") = 2
pGrid.Put("CellAlignment") = 1 ' flexAlignLeftCenter
pGrid.Put("Text") = pRecordset->Collect("CompanyName")
' Set the content of cell 3
pGrid.Put("Col") = 3
pGrid.Put("CellAlignment") = 1 ' flexAlignLeftCenter
pGrid.Put("Text") = pRecordset->Collect("ContactName")
' Set the content of cell 4
pGrid.Put("Col") = 4
pGrid.Put("CellAlignment") = 1 ' flexAlignLeftCenter
pGrid.Put("Text") = pRecordset->Collect("ContactTitle")
' Set the content of cell 5
pGrid.Put("Col") = 5
pGrid.Put("CellAlignment") = 1 ' flexAlignLeftCenter
pGrid.Put("Text") = pRecordset->Collect("Address")
' Set the content of cell 6
pGrid.Put("Col") = 6
pGrid.Put("CellAlignment") = 1 ' flexAlignLeftCenter
pGrid.Put("Text") = pRecordset->Collect("City")
' Set the content of cell 7
pGrid.Put("Col") = 7
pGrid.Put("CellAlignment") = 1 ' flexAlignLeftCenter
pGrid.Put("Text") = pRecordset->Collect("Region")
' Set the content of cell 8
pGrid.Put("Col") = 8
pGrid.Put("CellAlignment") = 1 ' flexAlignLeftCenter
pGrid.Put("Text") = pRecordset->Collect("PostalCode")
' Set the content of cell 9
pGrid.Put("Col") = 9
pGrid.Put("CellAlignment") = 1 ' flexAlignLeftCenter
pGrid.Put("Text") = pRecordset->Collect("Country")
' Set the content of cell 10
pGrid.Put("Col") = 10
pGrid.Put("CellAlignment") = 1 ' flexAlignLeftCenter
pGrid.Put("Text") = pRecordset->Collect("Phone")
' Set the content of cell 11
pGrid.Put("Col") = 11
pGrid.Put("CellAlignment") = 1 ' flexAlignLeftCenter
pGrid.Put("Text") = pRecordset->Collect("Fax")
' Fetch the next row
pRecordset->MoveNext
' Increment the counter
row += 1
WEND
' Select the first cell
pGrid.Put("Row") = 1
pGrid.Put("Col") = 1
' Close the recordset
pRecordset->Close
' Close the connection
pConnection->Close
' // Delete the recordset
Delete pRecordset
' // Delete the connection
Delete pConnection
' // Display the window
ShowWindow(hwndMain, nCmdShow)
UpdateWindow(hwndMain)
' // Dispatch Windows messages
DIM uMsg AS MSG
WHILE (GetMessageW(@uMsg, NULL, 0, 0) <> FALSE)
IF AfxCAxHostForwardMessage(GetFocus, @uMsg) = FALSE THEN
IF IsDialogMessageW(hwndMain, @uMsg) = 0 THEN
TranslateMessage(@uMsg)
DispatchMessageW(@uMsg)
END IF
END IF
WEND
FUNCTION = uMsg.wParam
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main window procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT
SELECT CASE uMsg
CASE WM_COMMAND
SELECT CASE LOWORD(wParam)
CASE IDCANCEL
' // If ESC key pressed, close the application by sending an WM_CLOSE message
IF HIWORD(wParam) = BN_CLICKED THEN
SendMessageW hwnd, WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
END SELECT
CASE WM_SIZE
' // Optional resizing code
IF wParam <> SIZE_MINIMIZED THEN
' // Retrieve a pointer to the CWindow class
DIM pWindow AS CWindow PTR = AfxCWindowPtr(hwnd)
' // Move the position of the button
IF pWindow THEN pWindow->MoveWindow GetDlgItem(hwnd, IDC_GRID), _
0, 0, pWindow->ClientWidth, pWindow->ClientHeight, CTRUE
END IF
CASE WM_DESTROY
' // Ends the application by sending a WM_QUIT message
PostQuitMessage(0)
EXIT FUNCTION
END SELECT
' // Default processing of Windows messages
FUNCTION = DefWindowProcW(hwnd, uMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
I thik that CDispInvoke has become easier to use than DispHelper, and without having to use a third party C++ DLL.