Introduction
I tried to use many grids of different types in Arabic mode but I failed, until I found GridCtrl
with source. And then I worked to adapt it to work with Arabic mode in different types of Views or Dialogs.
#define WS_EX_NOINHERITLAYOUT 0x00100000L
#define WS_EX_LAYOUT_RTL 0x00400000L
#define WS_EX_LAYOUTRTL 0x00400000L
#define WS_EX_NOINHERITLAYOUT 0x00100000L
#define WS_EX_NOINHERIT_LAYOUT 0x00100000L
BOOL CGridCtrl::Initialise()
{
..............
..............
..............
if (::IsWindow(m_hWnd))
{
ModifyStyleEx(0, 0x00400000L, 0);
ModifyStyleEx(0, WS_EX_RTLREADING, 0);
ModifyStyleEx(0, WS_EX_RIGHT, 0);
ModifyStyleEx(0, WS_EX_CLIENTEDGE, 0);
}
..............
..............
..............
..............
return TRUE;
}
BOOL CGridCtrl::Create(const RECT& rect, CWnd* pParentWnd,
UINT nID, DWORD dwStyle)
{
..............
..............
..............
DWORD dwExStyle;
if ( bCreateOnView )
{
if (!CWnd::Create(GRIDCTRL_CLASSNAME, NULL, dwStyle,
rect, pParentWnd, nID))
return FALSE;
Initialise();
}
else
{
dwExStyle ^= 0x00400000L;
dwExStyle ^= WS_EX_RTLREADING;
dwExStyle ^= WS_EX_RIGHT;
if (!CWnd::CreateEx(dwExStyle, GRIDCTRL_CLASSNAME, GRIDCTRL_CLASSNAME,
dwStyle, rect, pParentWnd, nID, NULL))
return FALSE;
}
..............
..............
..............
return TRUE;
}
void CGridCtrl::OnTimer(UINT nIDEvent)
{
..............
..............
..............
if (pt.y > rect.bottom)
{
SendMessage(WM_KEYDOWN, VK_DOWN, 0);
if (pt.x < rect.left)
pt.x = rect.left;
if (pt.x > rect.right)
pt.x = rect.right;
pt.y = rect.bottom;
OnSelecting(GetCellFromPt(pt));
}
else if (pt.y < nFixedRowHeight)
{
SendMessage(WM_KEYDOWN, VK_UP, 0);
if (pt.x < rect.left)
pt.x = rect.left;
if (pt.x > rect.right)
pt.x = rect.right;
pt.y = nFixedRowHeight + 1;
OnSelecting(GetCellFromPt(pt));
}
pt = origPt;
if (pt.x > rect.right)
{
SendMessage(WM_KEYDOWN, VK_RIGHT, 0);
if (pt.y < rect.top)
pt.y = rect.top;
if (pt.y > rect.bottom)
pt.y = rect.bottom;
pt.x = rect.right;
OnSelecting(GetCellFromPt(pt));
}
else if (pt.x < nFixedColWidth)
{
SendMessage(WM_KEYDOWN, VK_LEFT, 0);
if (pt.y < rect.top)
pt.y = rect.top;
if (pt.y > rect.bottom)
pt.y = rect.bottom;
pt.x = nFixedColWidth + 1;
OnSelecting(GetCellFromPt(pt));
}
..............
..............
..............
}
void CGridCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
..............
..............
..............
if (!IsCellVisible(next))
{
switch (nChar)
{
case VK_LEFT:
SendMessage(WM_HSCROLL, SB_LINERIGHT, 0);
bHorzScrollAction = TRUE;
break;
case VK_RIGHT:
SendMessage(WM_HSCROLL, SB_LINELEFT, 0);
bHorzScrollAction = TRUE;
break;
}
..............
..............
..............
}
Working with views:
void CSomeClassToWorkAsView::OnInitialUpdate()
{
CView::OnInitialUpdate();
if (!m_InitOn)
{
m_pGridCtrl = new CGridCtrl;
if (!m_pGridCtrl) return;
m_pGridCtrl->bCreateOnView = true;
CRect rect;
GetClientRect(rect);
m_pGridCtrl->Create(rect, this, 1001);
m_InitOn = true;
}
if (m_InitOn)
{
ReGetData();
}
}
Working with cells' merge:
for (col = 0; col < m_Grid.GetColumnCount(); col++)
{
m_Grid.SetItemBkColour(iRowCur, col, RGB(165, 27, 30));
m_Grid.SetItemFgColour(iRowCur, col, RGB(255, 255, 0));
}
m_Grid.SetSelectedRange(iRowCur, ID_QUTNAME, iRowCur, ID_SELX);
m_Grid.MergeSelectedCells();
Initialize normal control:
#define ID_COL_COUNT 0
#define ID_COL_DOCNO 1
#define ID_COL_DAYCOUNT 2
#define ID_COL_TDATESTART 3
#define ID_COL_TDATEEND 4
#define ID_COL_UAMTCHARGE 5
#define ID_COL_UAMTMOVE 6
#define ID_COL_UAMTENTRY 7
#define ID_COL_UAMTOTHER 8
#define ID_COL_UAMTTOTAL 9
#define ID_COL_COSTCNTR 10
#define ID_COL_MEMO 11
m_Grid.DeleteAllItems();
UpdateWindow();
m_Grid.GetDefaultCell(FALSE, FALSE)->SetBackClr(RGB(0xFF, 0xFF, 0xE0));
m_Grid.SetFixedColumnSelection(false);
m_Grid.SetFixedRowSelection(false);
m_Grid.SetHeaderSort(TRUE);
m_Grid.EnableColumnHide();
m_Grid.SetColumnCount(12);
m_Grid.SetRowCount(1);
m_Grid.SetAutoSizeStyle();
m_Grid.SetCompareFunction(CGridCtrl::pfnCellNumericCompare);
m_Grid.SetFixedRowCount(1);
m_Grid.SetFixedColumnCount(1);
GV_ITEM Item;
Item.mask = GVIF_TEXT|GVIF_PARAM|GVIF_FORMAT;
Item.nFormat = DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS;
Item.nState = 0;
Item.row = 0;
Item.col = ID_COL_COUNT;
Item.strText = "�";
m_Grid.SetItem(&Item);
Item.row = 0;
Item.col = ID_COL_DOCNO;
Item.strText = "��� �������";
m_Grid.SetItem(&Item);
Item.row = 0;
Item.col = ID_COL_DAYCOUNT;
Item.strText = "��� ������";
m_Grid.SetItem(&Item);
Item.row = 0;
Item.col = ID_COL_TDATESTART;
Item.strText = "��� �� ";
m_Grid.SetItem(&Item);
Item.row = 0;
Item.col = ID_COL_TDATEEND;
Item.strText = "������ �� ";
m_Grid.SetItem(&Item);
Item.row = 0;
Item.col = ID_COL_UAMTCHARGE;
Item.strText = "��� �����";
m_Grid.SetItem(&Item);
Item.row = 0;
Item.col = ID_COL_UAMTMOVE;
Item.strText = "�. ������";
m_Grid.SetItem(&Item);
Item.row = 0;
Item.col = ID_COL_UAMTENTRY;
Item.strText = "�. ������";
m_Grid.SetItem(&Item);
Item.row = 0;
Item.col = ID_COL_UAMTOTHER;
Item.strText = "�������";
m_Grid.SetItem(&Item);
Item.row = 0;
Item.col = ID_COL_UAMTTOTAL;
Item.strText = "������";
m_Grid.SetItem(&Item);
Item.row = 0;
Item.col = ID_COL_COSTCNTR;
Item.strText = "���� �����";
m_Grid.SetItem(&Item);
Item.row = 0;
Item.col = ID_COL_MEMO;
Item.strText = _T("������� ");
m_Grid.SetItem(&Item);
m_Grid.AutoSize();
m_Grid.ExpandLastColumn();
m_Grid.SetEditable(true);
m_Grid.SetRowResize(false);
void CSomeClassToWork::SetRowColItem(int row)
{
for (int col = 0; col < m_Grid.GetColumnCount(); col++)
{
CString str;
GV_ITEM Item;
Item.mask = GVIF_TEXT|GVIF_PARAM|GVIF_FORMAT;
Item.nFormat = DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS;
Item.nState = 0;
Item.row = row;
Item.col = col;
if ( col == ID_COL_COUNT )
{
CString sTemp;
sTemp.Format("%d", row);
Item.strText = sTemp;
}
if ( col == ID_COL_DOCNO )
Item.strText = _T("");
if ( col == ID_COL_DAYCOUNT )
Item.strText = _T("00");
if ( ( col >= ID_COL_COSTCNTR ) && ( col <= ID_COL_MEMO ) )
Item.strText = _T("");
if ( ( col >= ID_COL_UAMTCHARGE ) && ( col <= ID_COL_UAMTTOTAL ) )
Item.strText = _T("0.00");
if ( ( col >= ID_COL_TDATESTART ) && ( col <= ID_COL_TDATEEND ) )
Item.strText = _T(" - - ");
m_Grid.SetItem(&Item);
m_Grid.SetItemState(row, col,
m_Grid.GetItemState(row, col) & ~GVIS_READONLY);
if ( col == ID_COL_DOCNO )
{
m_Grid.SetItemState(row, col,
m_Grid.GetItemState(row, col) & ~GVIS_READONLY);
if (!m_Grid.SetCellType(row, col, RUNTIME_CLASS(CGridCellNormal)))
return;
}
if ( ( col >= ID_COL_COSTCNTR ) && ( col <= ID_COL_MEMO ) )
{
m_Grid.SetItemState(row, col,
m_Grid.GetItemState(row, col) & ~GVIS_READONLY);
if (!m_Grid.SetCellType(row, col, RUNTIME_CLASS(CGridCellNormal)))
return;
}
if ( ( col >= ID_COL_TDATESTART ) && ( col <= ID_COL_TDATEEND ) )
{
if (!m_Grid.SetCellType(row, col, RUNTIME_CLASS(CGridCellDateTime)))
return;
CGridCellDateTime *pCell =
(CGridCellDateTime*) m_Grid.GetCell(row, col);
COleDateTime m_cTime;
m_cTime = COleDateTime::GetCurrentTime();
pCell->m_cTime = m_cTime;
CString sTDate;
sTDate = m_cTime.Format("%Y-%m-%d");
m_Grid.SetItemText(row, col, sTDate);
}
}
m_Grid.SetItemText(row, ID_COL_DOCNO , sDocNo );
m_Grid.SetItemText(row, ID_COL_DAYCOUNT , sDayCount );
m_Grid.SetItemText(row, ID_COL_TDATESTART , sTDateStart );
m_Grid.SetItemText(row, ID_COL_TDATEEND , sTDateEnd );
m_Grid.SetItemText(row, ID_COL_UAMTCHARGE , suAmtTCharge );
m_Grid.SetItemText(row, ID_COL_UAMTMOVE , suAmtTMove );
m_Grid.SetItemText(row, ID_COL_UAMTENTRY , suAmtTEntry );
m_Grid.SetItemText(row, ID_COL_UAMTOTHER , suAmtTOther );
m_Grid.SetItemText(row, ID_COL_UAMTTOTAL , suAmtTTotal );
m_Grid.SetItemText(row, ID_COL_COSTCNTR , sCostCnt );
m_Grid.SetItemText(row, ID_COL_MEMO , sHMemo );
}
Have fun!