Solved

Modeless Dialog problem when passing values to it from socket

Posted on 2003-11-20
21
480 Views
Last Modified: 2013-11-20
Hi,

I have a socket class that receives some data, upon receiving this data it does this:

      if (command == "ONLINEUSERLIST")
      {
            //AfxMessageBox(strRecvd);
            ((CListUsersDlg*)m_pWnd)->doProcessOnlineUsers(strRecvd);
      }



void CListUsersDlg::doProcessOnlineUsers(CString strRecvd)
{
      AfxMessageBox(strRecvd);

      char *received = strRecvd.GetBuffer(4096);
      char seps[] = " ";
      char *token;
      CString users;
                  
      token = strtok(received, seps);
      users = token; // what user here

      while (token != NULL)
      {
            m_ctlListUsers.AddString(users);

            token = strtok(NULL, seps);
            users = token; // client userName, to find the buddy file .ini to ammend/create
      }
}

but when m_ctlListUsers.AddString(users); is happens i get an assert error:

      { ASSERT(::IsWindow(m_hWnd)); return (int)::SendMessage(m_hWnd, LB_ADDSTRING, 0, (LPARAM)lpszItem); }

Call Stack:
CListBox::AddString(const char * 0x00a92c5c) line 669 + 46 bytes
CListUsersDlg::doProcessOnlineUsers(CString {"ONLINEUSERLIST"}) line 82
...

Context:

AddString(users)
+      lpszItem      0x00a92c5c "ONLINEUSERLIST"
-      m_hWnd      0x00000000
      unused      CXX0030: Error: expression cannot be evaluated
-      this      0x0012faa8 {COptionsDlg hWnd=0x00000000}
+      [COptionsDlg]      {COptionsDlg hWnd=0x00000000}
-      CWnd      {CWnd hWnd=0x00000000}
+      CCmdTarget      {CCmdTarget}
+      classCWnd      {"CWnd"}
+      m_hWnd      0x00000000
+      wndTop      {CWnd hWnd=0x00000000}
+      wndBottom      {CWnd hWnd=0x00000001}
+      wndTopMost      {CWnd hWnd=0xffffffff}
+      wndNoTopMost      {CWnd hWnd=0xfffffffe}
+      m_hWndOwner      0x00000000
      m_nFlags      0
      m_pfnSuper      0x00000000
      m_nMsgDragList      49370
      m_nModalResult      0
+      m_pDropTarget      0x00000000 {COleDropTarget}
+      m_pCtrlCont      0x00000000 {COleControlContainer}
+      m_pCtrlSite      0x00000000 {COleControlSite}
+      _messageEntries      0x005bee28 struct AFX_MSGMAP_ENTRY const * const CWnd::_messageEntries
+      messageMap      {...}
-      classCListBox      {"CListBox"}
+      m_lpszClassName      0x005e0504 "CListBox"
      m_nObjectSize      60
      m_wSchema      65535
      m_pfnCreateObject      0x00000000
+      m_pBaseClass      0x005bee08 struct CRuntimeClass const CWnd::classCWnd
+      m_pNextClass      0x00000000 {???}


How do i fix this from happening?

Thanks

0
Comment
Question by:nikon70
  • 10
  • 8
21 Comments
 

Author Comment

by:nikon70
ID: 9791777
oh and here is how i created the dialog:

void CBuddyChatDlg::OnContactsListcontacts()
{
      // TODO: Add your command handler code here
      //m_dListUsersDlg.DoModal();
      CListUsersDlg* dlg = new CListUsersDlg;

      dlg->SetSockConnection(&m_sConnectSocket); //added to help classes interact

      dlg->Create(IDD_LIST_USERS_DIALOG);
      dlg->ShowWindow(SW_SHOW);      
      // adding pointer for dialog to reference later to get correct dlg to chat to
      
}
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9795185
Have you attatched a listbox to your control variable m_ctlListUsers?

ie used class wizard to create a variable or subclassed a control to the variable.

The error message relates to no window being associated with your control
0
 

Author Comment

by:nikon70
ID: 9795941
Hi,

Yes the m_ctlListUsers is attatched my CListBox.

CListBox      m_ctlListUsers;

=/
0
 

Author Comment

by:nikon70
ID: 9795967
if you want to see the code:

http://212.158.234.59/BuddyChat_v2.rar

cheers.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9796423
Just to check, what happens if you add the line checking the contents of var users.  Is the expected value?

   users = token; // what user here
AfxMessageBox(users);
0
 

Author Comment

by:nikon70
ID: 9796447
i get a list of users, but then it tries to do:

m_ctlListUsers.AddString(users);

and it dies.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9796539
I am puzzled.  Please give the following a go to make certain your dlg and list are windows.



void CListUsersDlg::doProcessOnlineUsers(CString strRecvd)
{
ASSERT(GetSafeHwnd() != NULL);
ASSERT( m_ctlListUsers.GetSafeHwnd() != NULL);


     AfxMessageBox(strRecvd);

     char *received = strRecvd.GetBuffer(4096);
     char seps[] = " ";
     char *token;
     CString users;
               
     token = strtok(received, seps);
     users = token; // what user here

     while (token != NULL)
     {
          m_ctlListUsers.AddString(users);

          token = strtok(NULL, seps);
          users = token; // client userName, to find the buddy file .ini to ammend/create
     }
}

0
 

Author Comment

by:nikon70
ID: 9796645
Problem here:

ASSERT(m_ctlListUsers.GetSafeHwnd() != NULL);


-      m_ctlListUsers      {CListBox hWnd=0x00000000}
+      CWnd      {CWnd hWnd=0x00000000}
+      classCListBox      {"CListBox"}
-      this      0x0012fa4c {CBuddyChatDlg hWnd=???}
+      CDialog      {CDialog hWnd=0x002f07ec}
+      m_ctlListUsers      {CListBox hWnd=0x00000000}
+      _messageEntries      0x005bda18 struct AFX_MSGMAP_ENTRY const * const CListUsersDlg::_messageEntries
+      messageMap      {...}
+      m_Socket      0x00000082 {CConnSocket}
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9796671
Another thing to try

    while (token != NULL)
     {
          m_ctlListUsers.AddString(users);   //ADD BREAKPOINT HERE

use a breakpoint (F9 key) and single step to check when it fails and what value 'users' has.
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9796703
Ignore last comment.
I've just done a quickie dialog

in .h file

      //{{AFX_DATA(CAboutDlg)
      enum { IDD = IDD_ABOUTBOX };
      CListBox      m_lstUsers;
      //}}AFX_DATA

in .cpp file
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
      CDialog::DoDataExchange(pDX);
      //{{AFX_DATA_MAP(CAboutDlg)
      DDX_Control(pDX, IDC_LIST1, m_lstUsers);
      //}}AFX_DATA_MAP
}

Do you have code like that to link your list control to a control that exists?
0
 

Author Comment

by:nikon70
ID: 9796833
right let me start from the beginning:

i click search and a modeless dialog opens, from my CBuddyChatDlg, and opens a CListUsersDlg,

i then click a button on my CListUsersDlg box, view online users, which sends some data over a socket and then

data comes in from a socket which is passed to from my CConnSocket class to ((CListUsersDlg*)m_pWnd)->doProcessOnlineUsers(strRecvd);

which is where it does this: m_ctlListUsers.AddString(users);

ok, now yes in my CListUsersDlg.h i have:

public:
      void doProcessOnlineUsers(CString);
      void SetSockConnection(CConnSocket *);
      CListUsersDlg(CWnd* pParent = NULL);   // standard constructor

// Dialog Data
      //{{AFX_DATA(CListUsersDlg)
      enum { IDD = IDD_LIST_USERS_DIALOG };
      CListBox      m_ctlListUsers;
      //}}AFX_DATA

and in my CListUsersDlg.cpp i have:

void CListUsersDlg::DoDataExchange(CDataExchange* pDX)
{
      CDialog::DoDataExchange(pDX);
      //{{AFX_DATA_MAP(CListUsersDlg)
      DDX_Control(pDX, IDC_LISTUSERS, m_ctlListUsers);
      //}}AFX_DATA_MAP
}

does that all seem to be correct the way i am passing data and that i have the correct code in the correct class(s) ??

0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9796945
You posted earlier
void CBuddyChatDlg::OnContactsListcontacts()
{
     // TODO: Add your command handler code here
     //m_dListUsersDlg.DoModal();
     CListUsersDlg* dlg = new CListUsersDlg;

     dlg->SetSockConnection(&m_sConnectSocket); //added to help classes interact

     dlg->Create(IDD_LIST_USERS_DIALOG);
     dlg->ShowWindow(SW_SHOW);    
     // adding pointer for dialog to reference later to get correct dlg to chat to
     
}

and from your latest post
data comes in from a socket which is passed to from my CConnSocket class to ((CListUsersDlg*)m_pWnd)->doProcessOnlineUsers(strRecvd);


This m_pWnd is a pointer to the modeless CListUsersDlg dialog you create.  Please check your code to confirm.
Otherwise I can't see anything wrong with what you post.  (I assume IDC_LISTUSERS is the resource ID of a listbox).
In the OnInitDialog of your CListUsersDlg after it calls the base class OnInitDialog you could also check the list control has been correctly hooked.

CDialog::OnInitDialog();
ASSERT(m_ctlListUsers.GetSafeHwnd() != NULL);
0
 

Author Comment

by:nikon70
ID: 9797001
m_pWnd is set in my CConnSocket class and the code is:

void CConnSocket::SetParent(CDialog *pWnd)
{
      //set pointer
      m_pWnd = pWnd;
}

i also use this point for:

      if (command == "MSG")
      {
            //CString msg = "connsocket on receive if command == msg .. ";
            //AfxMessageBox(msg + strRecvd);

            ((CBuddyChatDlg*)m_pWnd) -> doProcessMsg(strRecvd); // receive a message

      }

and:

      if (command == "ONLINEUSERLIST")
      {
            //AfxMessageBox(strRecvd);
            ((CListUsersDlg*)m_pWnd)->doProcessOnlineUsers(strRecvd);
      }

is this right?

and yes  IDC_LISTUSERS is my list box resource, control name m_ctlListUsers
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9797562
    if (command == "MSG")
     {
          //CString msg = "connsocket on receive if command == msg .. ";
          //AfxMessageBox(msg + strRecvd);

          ((CBuddyChatDlg*)m_pWnd) -> doProcessMsg(strRecvd); // receive a message

     }

and:

     if (command == "ONLINEUSERLIST")
     {
          //AfxMessageBox(strRecvd);
          ((CListUsersDlg*)m_pWnd)->doProcessOnlineUsers(strRecvd);
     }

The first if statement casts m_pWnd to CBuddyChatDlg*, the second casts it to CListUsersDlg*,
One (or both) of these must be wrong.
I think your CListUsersDlg is a child of the buddy dialog so keep a pointer to it there and get it through the buddy.  (I assume the pointer to the CConnSocket is a pointer to your buddy so the second if should be something like

   if (command == "ONLINEUSERLIST")
     {
          //AfxMessageBox(strRecvd);
          ((CListUsersDlg*)((CBuddyChatDlg*)m_pWnd)->m_pWndListUserDlg)->doProcessOnlineUsers(strRecvd);
     }
0
 

Author Comment

by:nikon70
ID: 9798076
that is still causing the same error.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9802140
Can you e-mail it to me.  I'll have a look monday
{{ email addr removed -- DR / EE PE }}
0
 
LVL 44

Accepted Solution

by:
AndyAinscow earned 35 total points
ID: 9816652
I think you need to get at the dialog with the list in like this
((CBuddyChatDlg*)m_pWnd)->m_dListUsersDlg.m_ctlListUsers

You will need the list dlg as a public member and you ought to check it is initialised before passing the message onto it.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 11849719
My final comment should have solved it.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now