|
I have created a class derived from CMFCListCtrl in VS2010. The documentation I have found says to override OnCompareItems to supply my comparison process for sorting. I have added that override. However it is never called, the default do nothing virtual is still being used. When I use Class Wizard, the virtual OnCompareItems is not listed which probably means something. Any suggestions?
|
|
|
|
|
Richard Zey wrote: However it is never called...
What are you calling to start the sort process?
"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
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
I am not calling any function. I have assumed that when you click on the column header, the header control will initiate the sort. I am using the CMFCListCtry since the headr control allows mutiple column sorts and will display an up or down arrow showing the direction of the sort. I can catch the column click message and do the sorting but then I lose the two functions above.
|
|
|
|
|
Turns out that the problem is in the parameter types. The definition in afxlistctrl.h is
virtual int OnCompareItems(LPARAM lParam1, LPARAM lParam2, int iColumn);
My override was defined as
virtual int OnCompareItems(LPARAM lParam1, LPARAM lParam2, long iColumn);
As you get no error on build, I did not look closely enough.
|
|
|
|
|
I finally got my SQL Server broadcast to work, and I receive the correct data back to my socket.
bytesReceived = recv(sUDPSocket, recvbuf, recvbuflen, 0);
Now I need to get a copy of what's in the buffer, and pass it for further processing. I have learned that the buffer I made is a group of bytes, 1 char is 1 byte, so my recvbuf is set to 96.
Do I need to copy each byte 1 at at time?, or can they all be copied in one shot. If I do need to copy 1 at a time, do I use strcopy?
for ( int i = 0; bytesReceived -1; i++ ) {
strncpy ( pBuffer, recvbuf, 1 );
}
_process_SQL_BufferData(pBuffer, bytesReceived);
|
|
|
|
|
You can use strncpy[^] to copy the entire buffer at once.
strncpy (pBuffer, recvbuf, bytesReceived);
0100000101101110011001000111001011101001
|
|
|
|
|
I tried that but it only copied the first 2 bytes
char pBuffer[256]="";
strncpy (pBuffer, recvbuf, bytesReceived + 1);
_process_SQL_BufferData(pBuffer, bytesReceived);
I tried memcopy and it copied the whole thing, but I don't want to create a side effect to my receivebuffer.
char pBuffer[96];
memcpy (pBuffer, recvbuf, bytesReceived + 1);
_process_SQL_BufferData(pBuffer, bytesReceived);
|
|
|
|
|
What is the value of the bytesReceived variable?
0100000101101110011001000111001011101001
|
|
|
|
|
- recvbuf 0x0012f8a0 "T" char [256]
[0] 5 '' char
[1] 84 'T' char
[2] 0 char
[3] 83 'S' char
[4] 101 'e' char
[5] 114 'r' char
[6] 118 'v' char
[7] 101 'e' char
[8] 114 'r' char
[9] 78 'N' char
[10] 97 'a' char
[11] 109 'm' char
[12] 101 'e' char
[13] 59 ';' char
[14] 68 'D' char
[15] 69 'E' char
[16] 76 'L' char
[17] 76 'L' char
[18] 67 'C' char
[19] 53 '5' char
[20] 50 '2' char
[21] 49 '1' char
[22] 45 '-' char
[23] 48 '0' char
[24] 49 '1' char
[25] 59 ';' char
[26] 73 'I' char
[27] 110 'n' char
[28] 115 's' char
[29] 116 't' char
[30] 97 'a' char
[31] 110 'n' char
[32] 99 'c' char
[33] 101 'e' char
[34] 78 'N' char
[35] 97 'a' char
[36] 109 'm' char
[37] 101 'e' char
[38] 59 ';' char
[39] 83 'S' char
[40] 81 'Q' char
[41] 76 'L' char
[42] 69 'E' char
[43] 88 'X' char
[44] 80 'P' char
[45] 82 'R' char
[46] 69 'E' char
[47] 83 'S' char
[48] 83 'S' char
[49] 59 ';' char
[50] 73 'I' char
[51] 115 's' char
[52] 67 'C' char
[53] 108 'l' char
[54] 117 'u' char
[55] 115 's' char
[56] 116 't' char
[57] 101 'e' char
[58] 114 'r' char
[59] 101 'e' char
[60] 100 'd' char
[61] 59 ';' char
[62] 78 'N' char
[63] 111 'o' char
[64] 59 ';' char
[65] 86 'V' char
[66] 101 'e' char
[67] 114 'r' char
[68] 115 's' char
[69] 105 'i' char
[70] 111 'o' char
[71] 110 'n' char
[72] 59 ';' char
[73] 49 '1' char
[74] 48 '0' char
[75] 46 '.' char
[76] 53 '5' char
[77] 48 '0' char
[78] 46 '.' char
[79] 49 '1' char
[80] 54 '6' char
[81] 48 '0' char
[82] 48 '0' char
[83] 46 '.' char
[84] 49 '1' char
[85] 59 ';' char
[86] 59 ';' char
|
|
|
|
|
The strncpy function only copies two characters because it stop when it encounters a null character.
So you will either have to copy them one by one:
for ( int i = 0; bytesReceived -1; i++ )
{
pBuffer[i] = recvbuf[i];
}
or use memcpy:
memcpy (pBuffer, recvbuf, bytesReceived);
0100000101101110011001000111001011101001
|
|
|
|
|
What do you mean by
jkirkerx wrote: side effect to my receivebuffer.
0100000101101110011001000111001011101001
|
|
|
|
|
alter the data in the buffer, wipe it clean before I can get the data
|
|
|
|
|
If you are careful in your use of memcpy , make sure the receiving buffer is large enough and not to copy more than the source contains that should not happen.
0100000101101110011001000111001011101001
|
|
|
|
|
don't use text/string functions for binary data. There is memcpy and more for that.
|
|
|
|
|
I have two function to save/load information from/in a file.
My problem is that
for(int p=0;p<tamano_b;p++)
{
f.Read(&dato_b,sizeof(dato_b));
datos_b[p]=dato_b;
}
This line dont read well, only read the first date, and after read rubbish.
f.ReadString(ausente_b);
In this line read a empty CString
and so on..
Overcoat fail when read CString variable
This is my function:
int CAdestView::PegarVariables(void)
{
int tamano_b;
int x=0;
CString nombre_b;
double dato_b=0;
double *datos_b;
CString *datostxt_b;
CString datotxt_b;
CString ausente_b;
int escala_b=0;
CString etiqueta_b;
CString labels_b;
int precision_b=0;
int tipo_b=0;
CString error;
INT_PTR tam_vars;
int n = 1;
CString aux_nombre;
CString aux_nombre_lista;
bool salir = false;
bool encontrado = false;
CStdioFile f;
CAdestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CString path= GetUserHomeDir() + _T("\\temporal.dat");
f.Open( path, CFile::modeReadWrite | CFile::typeBinary);
if (f == NULL)
{
MessageBox (_T("fallo"));
return 0;
}
f.SeekToBegin();
tam_vars = pDoc->Variables.GetSize ();
if(f.Read(&x,sizeof(x))<0)
return 0;
for(int h=0;h<x;h++)
{
f.Read(&tipo_b,sizeof(tipo_b));
f.Read(&tamano_b,sizeof(tamano_b));
if(tipo_b==0)
{
datos_b=new double[tamano_b];
datostxt_b = NULL;
for(int p=0;p<tamano_b;p++)
{
f.Read(&dato_b,sizeof(dato_b));
datos_b[p]=dato_b;
}
}
else
{
datostxt_b=new CString[tamano_b];
for(int p=0;p<tamano_b;p++)
{
f.ReadString(datotxt_b);
datostxt_b[p]=datotxt_b;
}
}
f.ReadString(nombre_b);
f.ReadString(ausente_b);
f.Read(&escala_b,sizeof(escala_b));
f.ReadString(etiqueta_b);
f.ReadString(labels_b);
f.Read(&precision_b,sizeof(precision_b));
if(tam_vars == 0)
{
GetDocument()->Variables.Add(new CDatos(tipo_b,tamano_b,escala_b,nombre_b, datos_b,datostxt_b,etiqueta_b,labels_b, ausente_b,precision_b));
m_Lista.InsertItem(n+x,nombre_b);
}
else
{
salir = false;
for (int i = 0; i < (tam_vars +1); i++)
{
aux_nombre_lista = m_Lista.GetItemText (i, 0);
if (nombre_b == aux_nombre_lista)
{
encontrado = true;
break;
}
}
if (!encontrado)
{
salir = true;
aux_nombre = nombre_b;
}
while (!salir)
{
aux_nombre.Format (TEXT("%s%d"),nombre_b, n);
for (int i = 0; i < (tam_vars+1); i++)
{
aux_nombre_lista = m_Lista.GetItemText (i, 0);
if (aux_nombre_lista == aux_nombre)
{
encontrado = true;
n++;
break;
}
}
if (!encontrado)
salir = true;
else
encontrado = false;
}
pDoc->Variables.Add (new CDatos(tipo_b,tamano_b,escala_b,aux_nombre,datos_b,datostxt_b,etiqueta_b,labels_b,ausente_b,precision_b));
}
}
f.Close();
bool borrado=FALSE;
return 1;
}
what happen??
|
|
|
|
|
antonio343 wrote: what happen??
Impossible to say. Try using your debugger to step through the code and verify that the values you are reading from your data file are correct.
|
|
|
|
|
In addition to Richard's suggestion, narrow the problem down to just a small handful of lines. Upwards of 95% of the code you've shown is not part of the problem scope (i.e., is irrelevant).
"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
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
I did other example to prove somthing, I did :
CStdioFile f;
CString path= GetUserHomeDir() + _T("\\temporal.txt");
f.Open(path, CFile::modeCreate | CFile::modeWrite | CFile::typeText);
double a=9.8;
CString b=_T("hello");
f.WriteString(b);
f.Write(&a,sizeof(double));
f.Close();
I see the content from the file, and only wrote hello. This is the content from the file:
hello™™™™™#@
|
|
|
|
|
antonio343 wrote: I see the content from the file, and only wrote hello.
The above code shows you follow the word "hello" with a double value, so the file content is correct. You also do not show any code to read the file so I am still not sure what your problem is.
|
|
|
|
|
The content from the file isn't correct!!!!!
I wrote hello and 9.8 and it isn't the content of the file.
In adittion, I made a method to read the file
CStdioFile f;
CString b;
double a;
CString path= GetUserHomeDir() + _T("\\temporal.txt");
f.Open(path, CFile::modeRead | CFile::typeText);
f.ReadString(b);
f.Read(&a,sizeof(double));
f.Close();
And it dont read well. It read hello#@ and in the other variable, read rubbish
|
|
|
|
|
antonio343 wrote: The content from the file isn't correct!
Yes it is, you do not understand what you are writing. The line:
f.Write(&a,sizeof(double));
writes the double value exactly as it is held in memory as a binary value 8 bytes wide. If you wish to convert it to a textual representation then you need to format it into a text string with sprintf() or CString , using the appropriate format codes.
|
|
|
|
|
ok..
But I don't need to show.
In the first function that I post here, I need to copy the value of variable in a file, and after load the value in variable, I dont know how to do it, becouse I try with fread/fwrite, CFile class, CStdio class, and I don't get something.
The problem is the variable are several kind of dates, CString, double, int...
but I think that the main problem is save and load CString kind.
|
|
|
|
|
There is no problem with what you suggest, you merely need to ensure that what you try to read back exactly mirrors what you write. This means that you must read back the exact number of bytes that you have written in the first place. With elementary items (int , double , char etc.) this is not difficult, but with strings you need to add some extra information to know how many characters to read in; you could do this by adding an integer in front of the string that specifies its length. Alternatively, use one of the formatting functions to convert all your data to string items and use some form of field separation (e.g. CSV, XML) to write in lines of text which you can then reconvert when reading back.
|
|
|
|
|
I tried to do this:
int nLength = b.GetLength() + 1;
int nBytes = nLength * sizeof(TCHAR);
f.Write(&nLength, sizeof(int));
f.Write(b, nBytes);
f.Write(&a,sizeof(double));
And the problem is the same, this is the content of the file:
h o l a C a r a c o l a š™™™™™#@
|
|
|
|
|
"Here is the content of the file"...
Just how are you getting that output to show us? Is that from some editor or file dump utility?
If you write a file containing some binary data (and you do, both 'nLength' and 'a' are written to the file as plain binary data), and then you ask an editor to display the content of the file, of course you are going to get garbage.
Editors make the reasonable assumption that the entire data file is 'char' and will attempt to interpret the file in that way, rendering all the characters into some printable form, including trash characters as you observe.
For binary data, editors and other display programs are inappropriate for looking at the contents to see if it is correct. Raw binary file dumpers are the best for that, then you can see every byte.
|
|
|
|
|