Oh, and I always forget... But is the timeout routine called from the same thread? It depends upon the framework, but in .NET, for example, the timeouts get called from a thread pool... I don't remember offhand for MFC.
The dialog doesn't need to be modal... I'm on the road right now so I don't have access to my code. But if you followed the examples you should be fine.
For modeless dialog windows creates _new_ thread . I will try to create Modal dialog or I will change the functionality to not call any Anvil functions from timer messages. I need to update GUI each second. I can implement it with 1 sec timer if I do not call B_ functions. Then I need to place orders once per two minutes. That can be more complex because of my timer is in different thread. Could you please help how can I receive executions of my limit orders? Right now I want to call Order functions GetRemainingSize() GetExecutedSize() GetPosition() I also need to get information about existing positions.
Again, I'm not in front of my computer, but I'm pretty sure the MFC Create call does not create a new thread. This might require the dialog have a parent or owner, but I am sure that it doesn't need to be modal. MFC modal dialogs aren't even truly modal... They're implemented using the parent's message pump.
Your DoAnvilExtensionCommand() gets called from ANVILs main thread so you should not have a problem there. You can create dlg as follow: CDlg m_pCDlg = new CDlg(); m_pDlg->Create(IDD_DLG, ::AfxGetMainWnd()); m_pDlg->ShowWindow(SW_SHOW); You need to monitor stcokmovement or Process() if you are using C++ objects as observables. You can monitor these messages: M_POOL_UPDATE_ORDER M_POOL_EXECUTION M_REQ_NEW_ORDER etc... I'll post a new message with some debuging code you can use to debug all the messages sent
Yes you are right about MFC modal dialogs. But when I call Create() function, I create modeless dialog with its own thread. In Anvil example there is Create() function. DoModal() function creates Modal dialog with the same thread as parent process.
There is lots of discovering you need to do in simulation mode. Most impotantly msgs received when an order is paced, positions changed, etc ... Here is some sample code you can use to debug all messages. You can use this in the acct and stock Process() call. I tried to comment parts of it. <i> //-------------------------------------------------------------------------------- void CMyStock:rocess(const Message* message, Observable* from, const Message* additionalInfo) { try { switch(message->GetType()) { //----------------------------------------------------------------------------- case M_NW2_INSIDE_QUOTE: { // Do something ... } break; //----------------------------------------------------------------------------- // // NOT IMPLEMENTED - NOT IMPLEMENTED - NOT IMPLEMENTED - NOT IMPLEMENTED - NOT IMPLEMENTED // //----------------------------------------------------------------------------- case M_AI_NEW_MM_BOOK: case M_MARKET_IMBALANCE: case M_FLUSH_ATTRIBUTED_BOOK_FOR_STOCK: { // Do not care about these ones // Add to this case messages that you do not care about. } break; default: { // I want to log any unexpected msgs. Good for new version of the API becasue sometimes they have ne wmsgs MYLOGMACRO( "Not Implemented: ignored: -%s- - %s", m_Symbol.c_str(), ResolveMessageId(message->GetType(), additionalInfo).c_str() ); } break; }; } //-------------------------------------------------------------------------------- #define MSGTYPEDESC( XTYPE ) case XTYPE: sDesc = ""#XTYPE""; break; //-------------------------------------------------------------------------------- std::string CAnvilAccount::ResolveMessageId(int iMessageID, const Message* additionalInfo) { std::string sDesc; switch(iMessageID) { // Define all message you want descriptions for. Grab more from the // anvil message headers MSGTYPEDESC( M_RESP_REFRESH_SYMBOL ); MSGTYPEDESC( M_RESP_REFRESH_SYMBOL_FAILED ); default: { char buf[1028]; sprintf_s( buf, 1028, "DEFAULT: %d", iMessageID ); sDesc = buf; } break; } // Check additional Inof if ( additionalInfo != NULL ) sDesc += " - ADDITIONAL: " + ResolveMessageId( additionalInfo->GetType(), NULL ); return sDesc; } </i>
There is a function void WINAPI InitializeAnvilExtension() and I call here: if ( !g_pMainDlg ) { Observable* account = B_GetCurrentAccount(); const char* accountName = B_GetAccountName(account); CWnd* mainWnd = AfxGetMainWnd(); g_pMainDlg = new TraderDlg( account, mainWnd ); g_pMainDlg->Create(IDD_TRADER, mainWnd); } So I think I am creating my dialog from Anvil thread. And as it is modeless dialog then it has its own thread. Anvil example does not have my error because it does not process timer in child dialog. They process message OnOK() and then place orders. It seems OnOK() is running in a separate thread, don't know why there is no problem. I have to spend more time studying Anvil examples . Everybody thank you a lot for help!