I have a problem... I want to send/post a message to a CDocument object from a CDialog object. I know I have use WM_COMMAND message but the thing is that the CDialog object does not have any access to information of CDocument since it is created from another thread. What should I put in the parameter HWND? Is there a handle for CDocuments?
I just had to call some specific functions of my CDocument derived but I managed to by-pass it..
Anyway I solved my problem but academically speaking I still pose the same question. If someone wants to "trigger" with WM_COMMAND message a CDocument how does he references to it and what does he puts in the first parameter (HWND) of the Send/Post Message function?
You seem to be confused about both C++ and Windows here; you cannot cast a CDocument object to an HWND since the one is not derived from, or the same 'shape' as, the other. A CDocument object is an instance of a class and an HWND is a Windows handle. There is also no mechanism within the CDocument class to receive windows messages. You could create a special command that will be handled by your CDocument class, and then send that command to your main or view window. Alternatively you could call the method of your document directly after your dialog has completed by checking some value within your CDialog class. If you really want to understand command and message handling in MFC then read this excellent paper[^] which Iain Clarke[^] pointed me at only yesterday.
I don't think you can message directly to a CDocument, you probably have to message the CView associated with it. In another words, send message to CView and have CView interact with CDocument however it needs to.
Is there a way to parse command line options from a string/file? I'd prefer a standard library that works on Linux, but if there is some way to do it from boost or some other library please let me know.
Please note that I'm NOT talking about command line arguments that are passed to the main function (argv), instead the complete cmdline is saved in a file.
Hi! I am completely stuck with it and don't know what to do.
The actual code is pretty huge so i'll skip it and try to explain things. So.
I am trying to write an echo server using completion ports and AcceptEx winsock extension. So far i got a server which can accept only one client and it works. But. The problem is: it can accept one and the only one client. This is how it goes. Basically i am doing almost same things like in tutorials on the net, extending wsaoverlapped, passing my struct as a parameter (keydata) to createiocompletionport where i am specifying current operation (read, write, accept, etc), and on GetQueuedCompletionStatus i am getting my struct by casting it to returned overlapped struct - if you are familiar with this subject you know what i am talking about.
I am creating a server (in case of server app) thread where i am calling AcceptEx which completion then ends up in worker thread and then i am working only in this worker thread, while initial server thread just sleeps waiting for termination. So, when AcceptEx succeeds, i am creating a new my own defined struct, which extends wsaoverlapped and calling AcceptEx again, then processing other operations, like read, write etc. And there is a problem, when new client connects to a server, this new AcceptEx accepts new client connection, but then previous connection gets terminated and this new connection gets terminated too. I have just started learning IOCP and there is a question:
in my project there is one server thread, which first do:
1. creating main listen socket
1a. launching worker thread with GetQueuedCompletionStatus
2. creating this fancy, so called, OverlappedPlus struct which holds some info
3. creating new socket for AcceptEx call
4. binds on port and starts listen
4a. Setting current operation to IOAccept
5. call AcceptEx (with all required params including pointer to wsaoverlapped struct which is first in my OverlappedPlus struct) and goes to sleep forever.
----[ at this point controls jumps to worker thread ]----
1. GetQueuedCompletionStatus and then get OverlappedPlus.
2. Check which operation do we have? We got IOAccept (i have written separate functions for processing these "events"), ok, jump to OnIOAccept.
3. Create new OverlappedPlus struct, new socket for AcceptEx call, update completion port with this new socket and call AcceptEx which then have to wait for new client.
4. Process then any other IO operations.
And all this works fine while there is only one client. When new client connecting to a server app, everything gets terminated. What am i doing wrong?
In general the usual cause for that is that the listen/accept only occurs once.
Some reasons for that
- The processing is not threaded so the thread that is doing the accept is used to process or otherwise blocks.
- The accept must be restarted in some way (such as the windows async methods which must use Begin and End type methos appropriately.)
Well, in my case i got one server thread and one worker thread. Server thread first do all preparations, call listen and then call AcceptEx, and then just sleep. Every next call for AcceptEx occurs in worker thread, which processes everything. I am just wondering, how one worker thread can process everything? And more then one client? I am familiar with regular sockets, where you create a new thread for each accepted socket, but in this case i should just update my IO port with this newly created socket and worker thread will operate on every socket and every client connection?
I may not be following all your steps, but it appears all your threads end up waiting for socket accepts so everything is deadlocked.
Here's what I do...
Create a listener thread. Its job is to accept incoming connections and queue up the first completion job on the I/O completion port. I personally don't use AcceptEx anymore. I use a regular listener socket (bind()) and use an event (::WSAEventSelect(hListenSocket, hNetEvent, FD_ACCEPT);) to wake my listener thread when a connection request arrives. The listener thread proc just loops waiting on the event (and also a termination event for shutdown time). It looks like this:
1) creates a socket for the connection using ::WSAAccept()
2) creates an object of a class representing a client connection and adds this object to a collection
3) associates the new socket with the completion port using ::CreateIoCompletionPort()
4) creates/initializes a custom overlapped structure
5) Queues up a receive operation on the completion port using WSARecv()
That's it. I don't go to another thread to do the accept or anything else. From my OnAccept() call onward, the completion port threads handle all I/O.
For the I/O completion port I use a thread class. I create a pool of threads of this class, generally two threads per processor core works well. Pointers to these objects are kept in a collection so I can queue up a shutdown thread command for each pool thread on the completion port at shutdown time. The thread proc simply loops, waiting on ::GetQueuedCompletionStatus(), and handling each queued completion command, whether it be a receive, send, or exit thread command (determined by an opcode in the custom overlapped struct). I generally use a request-reply protocol (because it's easy, although I have added some unidirectional communication at times) so each processed receive command queues up a send command, and each processed send command queues up a receive command, all re-using the same custom overlapped struct.
Note: In case you didn't know...It's a common sockets programming mistake to assume the number of bytes requested to send or receive will all be sent or received in one call. This applies to I/O completion ports as well. Be prepared to handle sending or receiving remaining bytes when a completion event occurs. I personally track this in the custom overlapped struct.
Hey Mark, thanks for your reply - i was in fact doing almost same things :P. Well, but, thats it, and thank you so much!! I got rid of AcceptEx call, and, implemented accept event (like you do) and now it works!! Finally!
I got rid of AcceptEx call, and, implemented accept event (like you do) and now it works!
It was so long ago I forget why I don't use AcceptEx()...but I'm sure I couldn't get something to work the way I needed to
I do really like I/O completion ports. Not just for I/O... For native C++ apps they make a nice built-in thread pool for queuing operations on worker threads. Very efficient and Microsoft did most of the work
I am working with IOCP just for a 3 days now (current project requirement) and starting to love it. Completion ports are a way better then creating tons of threads for connections and tons of events as well - you got everything in one place, its like, kind of message loop, isnt it? having one struct, jumping from reading to writing and queuing stuff, defying operations, and performance for sure. Totally agree - IOCP is outstanding option - one port to rule them all Ok, back to coding
There are articles and even classes to tell how to dynamically move controls on forms.
I thought it should be a simple task to dynamically expand (MoveWindow) a control to fill available space under different user options, however, I cannot figure out how to dynamically determine the actual location of the new destination / size.
I have added an anchor button to get the location but I do not know how to dynamically get the location of this button.
I tried GetWindowRect , but that gives me location relative to the current window. GetClientRect gives me the actual size of the anchor button and that is no help either.
The “anchor button” is off the screen when the user selects the option and I use scroll to (up) bring it into view. Is is possible this is my problem and I need to recalculate the position after the scroll?
Still using VC6.0 and MFC, the app works for me, and no, updating to anything is not an option. Do not waste your and my time suggesting it.
Any constructive help will be as always appreciated.
Using GetClientRect() on your main window will tell you how much space is available, so you can resize your control to those dimensions to get it to fill the space. Also, I'm not sure how to do it in MFC, but in Win32 the structure filled by the BeginPaint() call will also give you the dimensions of the visible part of your window; maybe part of the CDC class will help.