|
Hello everyone,
I have created an editable list control (report style) with numbers. How could I save all content of list in a text file, each edited "number" below the other. I tried something like this:
void CDataDialog::OnOK()
{
CWnd* pwndCtrl = GetFocus();
int ctrl_ID = pwndCtrl->GetDlgCtrlID();
CString str;
ofstream outFile;
outFile.open("sample.txt");
switch (ctrl_ID)
{
case IDC_EDIT1:
GetDlgItemText(IDC_EDIT1, str);
for (int i = 1; i <= m_nCon; i++)
{
outFile << str <<endl;
outFile << m_nCon << endl;
}
outFile.close();
SetCell(::GetDlgItem(m_hWnd, IDC_LIST1),
str, nItem, nSubItem);
::SendDlgItemMessage(m_hWnd, IDC_EDIT1,
WM_KILLFOCUS, 0, 0);
::ShowWindow(::GetDlgItem(m_hWnd, IDC_EDIT1),
SW_HIDE);
break;
default:
break;
}
}
but by this way I can save only the last edited item in text file. Thank you in advance!!
|
|
|
|
|
Something like:
CStdioFile file("sample.txt", CFile::modeCreate);
int nCount = listControl.GetItemCount();
for (int x = 0; x < nCount; x++)
{
CString strText = listControl.GetItemText(x, 0);
file.WriteString(strText);
}
file.Close();
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
I wrote this:
void CDataDialog::OnBnClickedOk()
{
CStdioFile file("over1.txt", CFile::modeCreate);
int nCount = m_List.GetItemCount();
for (int x = 0; x < nCount; x++)
{
CString strText = m_List.GetItemText(x, 0);
file.WriteString(strText);
}
file.Close();
}
and when execute it I get this statement: "Debug assertion failed". Is this because I already use CString CDataDialog::GetItemText(HWND hWnd, int nItem, int nSubItem) const??? Sorry I didn't mention it in the first post.
CString CDataDialog::GetItemText(
HWND hWnd, int nItem, int nSubItem) const
{
LVITEM lvi;
memset(&lvi, 0, sizeof(LVITEM));
lvi.iSubItem = nSubItem;
CString str;
int nLen = 128;
int nRes;
do
{
nLen *= 2;
lvi.cchTextMax = nLen;
lvi.pszText = str.GetBufferSetLength(nLen);
nRes = (int)::SendMessage(hWnd,
LVM_GETITEMTEXT, (WPARAM)nItem,
(LPARAM)&lvi);
} while (nRes == nLen - 1);
str.ReleaseBuffer();
return str;
}
|
|
|
|
|
lolici wrote: ...and when execute it I get this statement: "Debug assertion failed". You'll need to step through the code using the debugger to find the line that is asserting.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
The problem is here:
int nCount = m_List.GetItemCount();
I need another function than GetItemCount?
|
|
|
|
|
That line is NOT asserting. You need to step into the GetItemCount() method (until you find an ASSERT() macro).
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
lolici wrote: I wrote this:
void CDataDialog::OnBnClickedOk()
{
CStdioFile file("over1.txt", CFile::modeCreate);
<pre>
<span class="code-keyword">int</span> nCount = m_List.GetItemCount();</pre></blockquote>
What is m_List? Where and how is it defiled/initialized?
lolici wrote: CString CDataDialog::GetItemText(
HWND hWnd, int nItem, int nSubItem) const
{
LVITEM lvi;
memset(&lvi, 0, sizeof(LVITEM));
lvi.iSubItem = nSubItem;
CString str;
int nLen = 128;
int nRes;
do
{
nLen *= 2;
lvi.cchTextMax = nLen;
lvi.pszText = str.GetBufferSetLength(nLen);
nRes = (int)::SendMessage(hWnd,
LVM_GETITEMTEXT, (WPARAM)nItem,
(LPARAM)&lvi);
} while (nRes == nLen - 1);
str.ReleaseBuffer();
return str;
}
Why do you iplement your own function rather than use CListCtrl::GetItemText (MFC) method?
|
|
|
|
|
m_list is the control variable I declared about list control. I used CListCtrl::GetItemText (MFC)
but didn't work either :/
|
|
|
|
|
Then please show your code how this variable was attached to the list control: did you use MFC DDX_... mechanism or something else?
|
|
|
|
|
Here it is :
public: CListCtrl m_List;
void CDataDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, m_List);
}
I could also upload the project or the executable if it is possible.
|
|
|
|
|
lolici wrote: I could also upload the project or the executable if it is possible.
Please, read the rules about asking the question here to know whether it is possible.
|
|
|
|
|
# define blHeadTable ((V_ROM1_FAR tblHead V_ROM2_FAR V_ROM3 *)(BL_HEAD_ADDRESS))
# define GetblDID1() (blHeadTable->DID[1])
I am a little confused in the first macro declaration.
Appreciate any explanation.
|
|
|
|
|
Basically it casts the fixed address BL_HEAD_ADDRESS as a pointer to some type:
# define someTypeAddr ((someType *)(BL_HEAD_ADDRESS))
In your case the type is V_ROM1_FAR tblHead V_ROM2_FAR V_ROM3 .
Assuming that V_ROM1_FAR and V_ROM2_FAR are something like far * , the type is a pointer in V_ROM3 that points to a tblHead pointer.
Effectively it will assign a pointer to a tblHead structure at a fixed address.
|
|
|
|
|
I understand it's like:
# define someTypeAddr ((someType *)(BL_HEAD_ADDRESS))
But the type:
V_ROM1_FAR tblHead V_ROM2_FAR V_ROM3
I am still a little confused with it.
int a Char short, is that similar?
Thanks
|
|
|
|
|
You have to lookup first how V_ROM1_FAR and V_ROM2_FAR are defined.
Then it will be something like
far * tblHead far * V_ROM3 far is a compiler and platform specific keyword. See Far pointer - Wikipedia[^].
See also Cx51 User's Guide: Abstract Pointers[^] (I did not found a better link that explains such castings).
|
|
|
|
|
Thanks, I understand it.
Looked into V_ROM2_FAR V_ROM3, V_ROM2_FAR be defined as const, V_ROM3 blank
|
|
|
|
|
i hv problem in using basic rules of dev c
|
|
|
|
|
|
Alvi ZaDa wrote: i hv problem in using basic rules of dev c
1. What is "hv"?
2. What is "dev c"?
What exactly is the "problem in using basic rules" you have?
|
|
|
|
|
|
Hello everyone!
I've used a list control to display data and an edit box to edit them. So I used this function:
void CDataDialog::SetCell(HWND hWnd1,
CString value, int nRow, int nCol)
I want to make this change:
void CDataDialog::SetCell(HWND hWnd1,
double value, int nRow, int nCol)
but I have problem with other functions such as GetDlgItemText which I don't know how to change. Here is the code:
void CDataDialog::SetCell(HWND hWnd1,
double value, int nRow, int nCol)
{
TCHAR szString[256];
swprintf(szString, value, 0);
LVITEM lvItem;
lvItem.mask = LVIF_TEXT;
lvItem.iItem = nRow;
lvItem.pszText = szString;
lvItem.iSubItem = nCol;
if (nCol >0)
::SendMessage(hWnd1, LVM_SETITEM,
(WPARAM)0, (WPARAM)&lvItem);
else
ListView_InsertItem(hWnd1, &lvItem);
}
CString CDataDialog::GetItemText(
HWND hWnd, int nItem, int nSubItem) const
{
LVITEM lvi;
memset(&lvi, 0, sizeof(LVITEM));
lvi.iSubItem = nSubItem;
CString str;
int nLen = 128;
int nRes;
do
{
nLen *= 2;
lvi.cchTextMax = nLen;
lvi.pszText = str.GetBufferSetLength(nLen);
nRes = (int)::SendMessage(hWnd,
LVM_GETITEMTEXT, (WPARAM)nItem,
(LPARAM)&lvi);
} while (nRes == nLen - 1);
str.ReleaseBuffer();
return str;
}
void CDataDialog::OnClickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
Invalidate();
HWND hWnd1 = ::GetDlgItem(m_hWnd, IDC_LIST1);
LPNMITEMACTIVATE temp = (LPNMITEMACTIVATE)pNMHDR;
RECT rect;
nItem = temp->iItem;
nSubItem = temp->iSubItem;
if (nSubItem == 0 || nSubItem == -1 || nItem == -1)
return;
CString str = GetItemText(hWnd1, nItem,
nSubItem);
RECT rect1, rect2;
ListView_GetSubItemRect(hWnd1, temp->iItem,
temp->iSubItem, LVIR_BOUNDS, &rect);
::GetWindowRect(temp->hdr.hwndFrom, &rect1);
::GetWindowRect(m_hWnd, &rect2);
int x = rect1.left - rect2.left;
int y = rect1.top - rect2.top;
if (nItem != -1)
::SetWindowPos(::GetDlgItem(m_hWnd, IDC_EDIT1),
HWND_TOP, rect.left + x, rect.top + 4,
rect.right - rect.left - 3,
rect.bottom - rect.top - 1, NULL);
::ShowWindow(::GetDlgItem(m_hWnd, IDC_EDIT1), SW_SHOW);
::SetFocus(::GetDlgItem(m_hWnd, IDC_EDIT1));
::Rectangle(::GetDC(temp->hdr.hwndFrom),
rect.left, rect.top - 1, rect.right, rect.bottom);
::SetWindowText(::GetDlgItem(m_hWnd, IDC_EDIT1), str);
*pResult = 0;
}
void CDataDialog::OnOK()
{
CWnd* pwndCtrl = GetFocus();
int ctrl_ID = pwndCtrl->GetDlgCtrlID();
double str;
switch (ctrl_ID)
{
case IDC_EDIT1:
GetDlgItemText(IDC_EDIT1, str);
SetCell(::GetDlgItem(m_hWnd, IDC_LIST1),
str, nItem, nSubItem);
::SendDlgItemMessage(m_hWnd, IDC_EDIT1,
WM_KILLFOCUS, 0, 0);
::ShowWindow(::GetDlgItem(m_hWnd, IDC_EDIT1),
SW_HIDE);
break;
default:
break;
}
}
Thank you in advance!
|
|
|
|
|
A list control can not store double values without additional handling. To set the text of an item to a floating point value it must be converted. Read the documentation of the used sprintf, _sprintf_l, swprintf, _swprintf_l, __swprintf_l[^] function.
So you have to use something like
WCHAR szString[256];
swprintf(szString, sizeof(szString) / sizeof(WCHAR), L"%G", value);
But it would be better to use _snprintf_s, _snprintf_s_l, _snwprintf_s, _snwprintf_s_l[^] here:
TCHAR szString[256];
_sntprintf_t(szString, sizeof(szString) / sizeof(TCHAR), _T("%G"), value);
To get a double value back when reading the cell text use _tstof (atof, _atof_l, _wtof, _wtof_l[^]):
double CDataDialog::GetItemDouble(HWND hWnd, int nItem, int nSubItem) const
{
CString str = GetItemText(hWnd, nItem, nSubItem);
return _tstof(str);
}
modified 20-Mar-17 9:01am.
|
|
|
|
|
I did it but I got this: "no suitable constructor exists from double to ATL::CStringT wchar_t StrTraitMFC__DLL<wchar_t,atl chtraitsctr<wchar_t="">>>" on
CString str = GetItemText(hWnd, nItem, nSubItem);
If I don't turn data from string to double could I "pass" them in a text file after edit them on the list view?
|
|
|
|
|
Sorry, forget to rename it during copy & paste. Should be named GetItemDouble :.
double CDataDialog::GetItemDouble(HWND hWnd, int nItem, int nSubItem) const
{
CString str = GetItemText(hWnd, nItem, nSubItem);
return _tstof(str);
}
|
|
|
|
|
Thank you very much Sir!It was compiled fine!! I got a message about "Unhandled exception" when tried to write on second dialog but I must have made a mistake on code.Could I save editable data from list view on text file without converting them from string type?
|
|
|
|
|