|
I can't tell. Is it a template? It doesn't look like one. What is type ?
Steve
|
|
|
|
|
I am trying to implement a "Column Chooser" for a ListCtrl in a Dialog based application - very much like Outlook's "Field Chooser" or Maarten Hoeben's "Report control - an Outlook 2000 style SuperGrid Report Control", here in The Code Project.
My problems so far are:
a. Maarten Hoeben's solution is way over the top for me, when I already have an existing application with a ListCtrl and HeaderCtrl already working (except for this extra feature!).
b. The CDialogBar solution is very neat and looks great but it is based on CFrameWnd, which contains things like OnBarCheck and OnUpdateControlBarMenu. My application is based on CDialog.
c. The standard CHeaderCtrl only supports Drag & Drop within the control - i.e. changing the order of columns by dragging and dropping. With the "Outlook" "Field Chooser" approach, I need to drag/drop columns from/onto the HeaderCtrl and the DialogBar.
Is this at all possible or am I asking the impossible?
All help gratefully received.
|
|
|
|
|
Hi,
I have this major issue, I have data coming into memory 200 times a second, this is filling up the RAM fairly quickly, so what I want to be able to do is read off past data that has already been stored, with out interrupting the writing of the new data from RAM. I was thinking a circular queue would do the trick but I'm not sure how to make sure that I do not lose any of the data being written to memory. The Reading can happen slower then the write, just as long as their is enough memory reserved which there will be.
Can anyone direct me to how I can achieve this. My main goal is to not lose any data but keep the reading going so that there is still enough memory for more frames to be loaded.
Thanks in advance.
|
|
|
|
|
Two threads, a reading thead and a writing thread, and std::queue. The writing thread pushes data onto the queue and the reading thread pops the data off the queue.
You may be right I may be crazy -- Billy Joel --
Within you lies the power for good, use it!!!
|
|
|
|
|
Hi,
I have been using Visual C++ 6.0 with MFC for a couple of years and have taught myself just enough to be dangerous. because of a new API that I need to use we are upgrading to Visual C++ 2005 (version 8.0). This is different enough to cause lots of confusion. Just looking for a good web site that will ease the transition of this change.
Buck Brown
|
|
|
|
|
|
i am new to multithreading in vc++, could u provide me some sites address where i can find tutorials to learn from basics.
|
|
|
|
|
l_d wrote: could u provide me some sites address where i can find tutorials...
Here is one such site.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
|
thanks to both of you,they are really helpful.
|
|
|
|
|
I glad they are helpful;)
|
|
|
|
|
Hello,
Does anyone know an easy way to stop the horizontal scrolling of the first (maybe the 2 first) columns in a CListView / CListCtrl. What I want is something that we can do in Excel with Window - Fix (hope, I translated correct). I have some text in the first 2 columns and many values in many other columns - and the text should always be visible.
I tried the whole day to find an article, but I didn't succeed. So any help would be great.
Thank's, Gerhard
|
|
|
|
|
That isn't a feature of the list control, however you can try a grid control like Chris Maunder's control right here on CP.
|
|
|
|
|
Anyone know why the .push_back function for a vector would overwrite the last entry. So for example, if i push 10 items into the vector. When i am done, the vector size shows 10 but the only item in there is the last one. I am totally clueless on this.
I call this function in a dll:
DLL_API int GetDATA(std::vector& pVectorDataInfoRecName, std::string sPath )
Then i process a DataInfoRecName pointer.
_tcscpy( pDataInfoRecName->szDate, TempString.c_str ());
Then i push it into the vector
pVectorDataInfoRecName.push_back(pDataInfoRecName);
|
|
|
|
|
Maybe the problem is what you are pushing in the vector and not the vector itself ?
LCI wrote: _tcscpy( pDataInfoRecName->szDate, TempString.c_str ());
Where does TempString come from ? if you place a break point there, what is the value of it ?
Are you certain you are not only creating only ONE pDataInfoRecName ? and that it's the same pointer that gets pushed back to the vector ?
|
|
|
|
|
I thought abou that and i debugged it a few times. Each item that i put in there, i would check the pointer to make sure. I initialized the pointer like this :
DataInfoRecName *pDataInfoRecName = new DataInfoRecName;
ZeroMemory( pDataInfoRecName, sizeof(DataInfoRecName) );
DataInfoRecName is a structure consisting of TCHARS.
What else can i look for?
|
|
|
|
|
Sorry, i did not respond to your questions..
TempString is an std::string
I read in one line of a file, dump it in TempString. Then i do some paring on TempString to remove Carriage return line feeds. Once that is done, i further parse the data and store in pDataInfoRecName.
When you say only 1 pdataInfoRecName, not sure what you mean. WHat i do is initialze it, then i use it in a loop. Each time around, the values change representing a different record.
|
|
|
|
|
Try to post the relevant code.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
I'm new in sockets programming especially in the asynchronous sockets. I'm writing a server and client apps with asynchronous sockets to (of course) exchange data between them.
This is the code for the client app:
<br />
int SocketClient::CreateSocket(HWND hwnd)<br />
{<br />
char cName[20];<br />
hostent * hostInfo;<br />
WSADATA wsStartup;<br />
WORD wVersion = MAKEWORD(2, 0);<br />
WSAStartup(wVersion, &wsStartup);<br />
currSocket = socket(AF_INET, SOCK_STREAM, 0);<br />
if(currSocket == INVALID_SOCKET)<br />
{<br />
MessageBox(NULL, "Socket não criado", "Erro", MB_OK);<br />
return -1;<br />
}<br />
gethostname(cName, 20);<br />
hostInfo = gethostbyname(cName);<br />
for(int i = 0 ; i < 8 ; i++)infosSocket.sin_zero[i] = 0;<br />
infosSocket.sin_family = AF_INET;<br />
infosSocket.sin_port = htons(2500);<br />
infosSocket.sin_addr = *((in_addr*)hostInfo->h_addr_list[0]);<br />
WSAAsyncSelect(currSocket, hwnd, WM_ASYNCMSG, FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE);<br />
return 0;<br />
}<br />
<br />
int SocketClient::ConnectToServer(HWND hwnd)<br />
{<br />
int iReturn = 0;<br />
iReturn = connect(currSocket, (sockaddr*)&infosSocket, sizeof(infosSocket));<br />
if(iReturn == SOCKET_ERROR)<br />
{<br />
char cTemp[10];<br />
int iResult = WSAGetLastError();<br />
itoa(iResult, cTemp, 10);<br />
MessageBox(NULL, cTemp, "", MB_OK);<br />
return -1;<br />
}<br />
WSAAsyncSelect(currSocket, hwnd, WM_ASYNCMSG, FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE);<br />
MessageBox(NULL, "OK", "", MB_OK);<br />
return 0;<br />
}<br />
And this is the server code:
<br />
int SocketServer::CreateSocket(HWND hwnd)<br />
{<br />
SocketServer::iBytesRecieved = 0;<br />
int iReturn = 0;<br />
WSADATA wsStartup;<br />
WORD wVersion = MAKEWORD(2,0);<br />
WSAStartup(wVersion, &wsStartup);<br />
currSocket = socket(AF_INET, SOCK_STREAM, 0);
if(currSocket == INVALID_SOCKET)<br />
{<br />
MessageBox(NULL, "Socket não criado", "Erro", MB_OK);<br />
return -1;<br />
}<br />
socketInfo.sin_family = AF_INET;<br />
socketInfo.sin_port = htons(2500);<br />
socketInfo.sin_addr.s_addr = INADDR_ANY;<br />
for(int i = 0 ; i < 8 ; i++)socketInfo.sin_zero[i]=0;<br />
iReturn = bind(currSocket, (sockaddr*)&socketInfo, sizeof(sockaddr));
if(iReturn == SOCKET_ERROR)<br />
{<br />
int iError = WSAGetLastError();<br />
MessageBox(NULL, "Erro", "", MB_OK);<br />
return iError;<br />
}<br />
WSAAsyncSelect(currSocket, hwnd, WM_ASYNCMSG, FD_ACCEPT|FD_CLOSE|FD_READ|FD_WRITE);<br />
return 0;<br />
}<br />
<br />
void SocketServer::ListenConnections()<br />
{<br />
listen(currSocket, 5);<br />
}<br />
<br />
SOCKET SocketServer::AcceptConnection(HWND hwnd)<br />
{<br />
SOCKET tempSocket = 0;<br />
int iSize = sizeof(sockaddr_in);<br />
tempSocket = accept(currSocket, (sockaddr*)&socketInfo, &iSize);<br />
WSAAsyncSelect(tempSocket, hwnd, WM_ASYNCMSG, FD_READ|FD_WRITE|FD_CLOSE);<br />
return tempSocket;<br />
}<br />
Now the questions:
The SendData and RecieveData funcs that contains send and recv funcs respectively, needs to be in a thread for that FD_READ and FD_WRITE messages will be sended?
In the ConnectToServer func, when I start the server and the client app, I've received WSAEWOULDBLOCK message. If I call this funcition again I receive the WSAEISCONN message. This means that my socket is connected? If so, why I receive the WSAEWOULDBLOCK message first?
In some sites that I've readed some tutorials, they say that, in the FD_WRITE message I need to have some caution because this message is sent when there are more space in the buffer with which to write data. Can someone explains tis to me?
Sorry for this long post fellows, but I need a help in this.
|
|
|
|
|
Alex Cutovoi wrote: The SendData and RecieveData funcs that contains send and recv funcs respectively, needs to be in a thread for that FD_READ and FD_WRITE messages will be sended?
Since you've used WSAAsyncSelect() specifying the FD_READ and FD_WRITE flags you will be notified
when there is data available to be read from the socket and when the socket is ready to accept
send data. This notification will be in the form of a window message (WM_ASYNCMSG) so you could
send/recv data on the UI htread that processes this message. You can also send/recv on other
threads. Just make sure you use some form of synchronization - sockets ops are not thread safe.
Alex Cutovoi wrote: In the ConnectToServer func, when I start the server and the client app, I've received WSAEWOULDBLOCK message. If I call this funcition again I receive the WSAEISCONN message. This means that my socket is connected? If so, why I receive the WSAEWOULDBLOCK message first?
WSAEWOULDBLOCK indicates that an asynchronous socket operation has started but didn't complete
immediately. If you want to be notified when a connect() call completes then you should add the
FD_CONNECT flag to your WSAAsyncSelect() flags.
Alex Cutovoi wrote: In some sites that I've readed some tutorials, they say that, in the FD_WRITE message I need to have some caution because this message is sent when there are more space in the buffer with which to write data. Can someone explains tis to me?
Read the details of using FD_WRITE carefully in the docs. From WSAAsyncSelect() -
"The FD_WRITE event is handled slightly differently. An FD_WRITE message is posted when a socket
is first connected with connect or WSAConnect (after FD_CONNECT, if also registered) or accepted
with accept or WSAAccept, and then after a send operation fails with WSAEWOULDBLOCK and buffer
space becomes available. Therefore, an application can assume that sends are possible starting
from the first FD_WRITE message and lasting until a send returns WSAEWOULDBLOCK. After such a
failure the application will be notified that sends are again possible with an FD_WRITE message."
Always check the return code on send() and recv() calls to make sure the number of bytes requested
were actually sent or received. A send() or recv() is successful even if only ONE byte gets sent
or received. You'll need to be ready to send remaining unsent bytes and/or receive remaining
unreceived bytes.
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
Thanks again Mark, I've suspected that WSAEWOULDBLOCK message indicates what you said. I comproved this studying some code samples and noticing the WSAEISCONN message. Just a question of pay attention. FYI, I'm developing my apps with Win32, not a single gout of MFC.
I'm very new in this subject, I'm developing my app based on your answer about my question of sockets: Socket curious error
Very thanks.
I have some questions yet:
Mark Salsbery wrote: Since you've used WSAAsyncSelect() specifying the FD_READ and FD_WRITE flags you will be notified
when there is data available to be read from the socket and when the socket is ready to accept
send data. This notification will be in the form of a window message (WM_ASYNCMSG) so you could
send/recv data on the UI thread that processes this message. You can also send/recv on other
threads. Just make sure you use some form of synchronization - sockets ops are not thread safe.
So, do I need to put the SendData and RecieveData functions in a thread right? Can you give me a sample?
Mark Salsbery wrote: Always check the return code on send() and recv() calls to make sure the number of bytes requested
were actually sent or received. A send() or recv() is successful even if only ONE byte gets sent
or received. You'll need to be ready to send remaining unsent bytes and/or receive remaining
unreceived bytes.
This is the hard part, how can I check in app there unsent bytes?
This is a topic that I don't domain yet, I'll be very grateful if you can answer my questions again.
|
|
|
|
|
Alex Cutovoi wrote: So, do I need to put the SendData and RecieveData functions in a thread right? Can you give me a sample?
You don't need to but you can. If there's so much data being sent and received that it degrades
the UI performance then it's probably a good idea. If you only transfer small amounts not very
often then you could leave your send/recv calls on the UI thread.
Alex Cutovoi wrote: This is the hard part, how can I check in app there unsent bytes?
The return value of the socket send() and recv() APIs are slightly different.
Both return SOCKET_ERROR if an error occurs, which means no bytes were transferred. For an async
socket if the error was WSAEWOULDBLOCK then it means data could't be transferred right away (no
bytes were received or send buffer is full) so you'll need to try again.
For send(), a successful return value is the number of bytes sent, which may not be all the bytes
you requested to be sent.
For recv(), a successful return value is the number of bytes received, which may not be all the
bytes you requested to be received. If recv() returns 0 that means the connection has been
closed.
So, a generic example of handling these return values could be something like this:
int nBytesToRecv = ...;
BYTE *pRecvBytes = ...;
while (nBytesToRecv > 0)
{
int nBytesReceived = ::recv(sock, (char*)pRecvBytes, nBytesToRecv, 0);
if (nBytesReceived == SOCKET_ERROR)
{
int nSockError = ::WSAGetLastError();
if (nSockError != WSAEWOULDBLOCK)
{
break;
}
}
else
{
nBytesToRecv -= nBytesReceived;
if (nBytesToRecv > 0)
pRecvBytes += nBytesReceived;
}
}
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
Very thanks mike, I have a direction now.
But one more thing, I want to send a struct between the apps. To fill the nBytesToRecv var, in my case, just I call the sizeof() func to fill it?
Thanks for the help in this topic.
|
|
|
|
|
Alex Cutovoi wrote: To fill the nBytesToRecv var, in my case, just I call the sizeof() func to fill it?
Generally yes. As long as the two ends use the same byte ordering for multi-byte numeric types
(int, etc.). Both ends should be compiled using the same structure padding as well.
Mark
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
Thanks mark, now I get some more knowledge to code my app
|
|
|
|
|