EnumSession.cpp
上传用户:royluo
上传日期:2007-01-05
资源大小:1584k
文件大小:7k
源码类别:

游戏

开发平台:

Visual C++

  1. // EnumSession.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "tanks.h"
  5. #include "dplay.h"
  6. #include "EnumSession.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. BOOL g_bEnumAll;    // Global flag used in enum session call back.
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CEnumSession dialog
  15. CEnumSession::CEnumSession(LPDIRECTPLAY2 pIDP, GUID *pSessionGuid)
  16.     : CDialog(CEnumSession::IDD, NULL),
  17.       m_pIDP(pIDP),
  18.       m_pSessionGuid(pSessionGuid),
  19.       m_dwTimeOut(0)
  20. {
  21.     //{{AFX_DATA_INIT(CEnumSession)
  22.         // NOTE: the ClassWizard will add member initialization here
  23.     //}}AFX_DATA_INIT
  24.     g_bEnumAll = FALSE;     // By default don't list all sessions.
  25. }
  26. void CEnumSession::DoDataExchange(CDataExchange* pDX)
  27. {
  28.     CDialog::DoDataExchange(pDX);
  29.     //{{AFX_DATA_MAP(CEnumSession)
  30.     DDX_Control(pDX, IDC_ENUMSESSION_TEXT, m_Static);
  31.     DDX_Control(pDX, IDC_ENUMSESSION_LIST, m_ListBox);
  32.     //}}AFX_DATA_MAP
  33. }
  34. BEGIN_MESSAGE_MAP(CEnumSession, CDialog)
  35.     //{{AFX_MSG_MAP(CEnumSession)
  36.     ON_BN_CLICKED(IDC_REFRESH, OnRefresh)
  37.     //}}AFX_MSG_MAP
  38. END_MESSAGE_MAP()
  39. /////////////////////////////////////////////////////////////////////////////
  40. // CEnumSession message handlers
  41. void CEnumSession::OnRefresh() 
  42. {
  43.     EmptyListBox();
  44.     g_bEnumAll = (1 == ((CButton*)GetDlgItem(IDC_RADIO_ENUMALL))->GetCheck());
  45.     EnumSession();
  46. }
  47. void CEnumSession::OnCancel() 
  48. {
  49.     EmptyListBox();
  50.     CDialog::OnCancel();
  51. }
  52. void CEnumSession::OnOK() 
  53. {
  54.     int ind = m_ListBox.GetCurSel();
  55.     if (CB_ERR == ind)
  56.     {
  57.         ASSERT(m_ListBox.GetCount());   // We shouldn't be here if list is empty
  58.         AfxMessageBox("No session was selected.nSelect one or press Cancel");
  59.         return;
  60.     }
  61.     *m_pSessionGuid = *(LPGUID)m_ListBox.GetItemData(ind);
  62.     // Now we can empty the list box.
  63.     EmptyListBox();
  64.     CDialog::OnOK();
  65. }
  66. BOOL CEnumSession::OnInitDialog() 
  67. {
  68.     CDialog::OnInitDialog();
  69.     
  70.     m_Static.SetWindowText("Press Refresh to start looking for sessions");
  71.     GetDlgItem(IDC_REFRESH)->SetFocus();
  72.     GetDlgItem(IDOK)->EnableWindow(FALSE);  // We can't press OK w/o a session
  73.     SetDefID(IDC_REFRESH);
  74.     if (g_bEnumAll)
  75.     {
  76.         ((CButton*)GetDlgItem(IDC_RADIO_ENUMALL))->SetCheck(TRUE);
  77.     } else
  78.     {
  79.         ((CButton*)GetDlgItem(IDC_RADIO_JOINTOFIRST))->SetCheck(TRUE);
  80.     }
  81.     
  82.     return TRUE;  // return TRUE unless you set the focus to a control
  83.                   // EXCEPTION: OCX Property Pages should return FALSE
  84. }
  85. BOOL FAR PASCAL 
  86. EnumSessionsCallback(
  87.     LPCDPSESSIONDESC2 lpSessionDesc, LPDWORD lpdwTimeOut,
  88.     DWORD dwFlags, LPVOID lpContext)
  89. {
  90.     HWND hWnd = (HWND)lpContext;
  91.     HGLOBAL hGuid;
  92.     LPGUID lpGuid;
  93.     LONG iIndex;
  94.     // Determine if the enumeration has timed out.
  95.     if (dwFlags & DPESC_TIMEDOUT)
  96.         return FALSE;               // Do not try again
  97.     // Store the session name in the list
  98.     iIndex = SendDlgItemMessage(hWnd, IDC_ENUMSESSION_LIST, LB_ADDSTRING,
  99.         (WPARAM)0, (LPARAM)lpSessionDesc->lpszSessionNameA);
  100.     if (CB_ERR == iIndex)
  101.         goto FAILURE;
  102.     // Make space for the session instance GUID.
  103.     hGuid = GlobalAlloc(GHND, sizeof(GUID));
  104.     if (! hGuid)
  105.         goto FAILURE;
  106.     lpGuid = (LPGUID)GlobalLock(hGuid);
  107.     if (NULL == lpGuid)
  108.     {
  109.         GlobalUnlock(hGuid);
  110.         goto FAILURE;
  111.     }
  112.     // Store the pointer to the GUID in the list.
  113.     *lpGuid = lpSessionDesc->guidInstance;
  114.     SendDlgItemMessage(hWnd, IDC_ENUMSESSION_LIST, LB_SETITEMDATA,
  115.         (WPARAM) iIndex, (LPARAM) lpGuid);
  116.     // We can decrease the timeout here, after the user is displayed with
  117.     // a session
  118.     *lpdwTimeOut = 0;
  119.     // Check if we can leave after the first session was found.
  120.     if (! g_bEnumAll)
  121.         return FALSE;
  122. FAILURE:
  123.     return TRUE;                   // Try again
  124. }
  125. void
  126. CEnumSession::EnumSession()
  127. {
  128.     // Put an hourglass cursor
  129.     CWaitCursor wc;
  130.     // Set static caption
  131.     m_Static.SetWindowText ("Looking for sessions. This may take a minute.");
  132.     // Disable all buttons
  133.     GetDlgItem(IDCANCEL)->EnableWindow(FALSE);
  134.     GetDlgItem(IDOK)->EnableWindow(FALSE);
  135.     GetDlgItem(IDC_REFRESH)->EnableWindow(FALSE);
  136.     // Enumerate sessions
  137.     DPSESSIONDESC2 SessionDesc;
  138.     ZeroMemory(&SessionDesc, sizeof(DPSESSIONDESC2));
  139.     SessionDesc.dwSize = sizeof(DPSESSIONDESC2);
  140.     SessionDesc.guidApplication = TANKS_GUID;
  141.     // Set the timeout value.
  142.     // We start with 0 (means DPlay put its own value). If we are
  143.     // called again then we restart with 20sec. and after that we mulitply
  144.     // by 2 until we reach 80sec.
  145.     if (m_dwTimeOut < 60000)
  146.     {   
  147.         if (! m_dwTimeOut)         // We don't want to multiply zero..
  148.             m_dwTimeOut = 20000;   // 20 sec.
  149.         else
  150.             m_dwTimeOut *= 2;
  151.     }
  152.     HRESULT hr = m_pIDP->EnumSessions(
  153.         &SessionDesc, 
  154.         m_dwTimeOut, 
  155.         EnumSessionsCallback,
  156.         (LPVOID)m_hWnd, 
  157.         DPENUMSESSIONS_AVAILABLE
  158.         );
  159.     if FAILED(hr)
  160.     {
  161.         TRACE ("EnumSessions failed with error code %uln", hr);
  162.         m_Static.SetWindowText("Can not enumerate sessions.");
  163.         // Make the Cancel button the only option.
  164.         GetDlgItem(IDCANCEL)->EnableWindow(TRUE);
  165.         GetDlgItem(IDCANCEL)->SetFocus();
  166.         SetDefID(IDCANCEL);
  167.         return;
  168.     }
  169.     // Enable Cancel and Refresh buttons.
  170.     GetDlgItem(IDCANCEL)->EnableWindow(TRUE);
  171.     GetDlgItem(IDC_REFRESH)->EnableWindow(TRUE);
  172.     // Set static caption
  173.     if (! m_ListBox.GetCount())
  174.     {   // No session were found.
  175.         m_Static.SetWindowText ("No sessions found. "
  176.             "To try again press the refresh button.");
  177.     } else 
  178.     {   // We found a session.
  179.         // Set the text.
  180.         m_Static.SetWindowText ("Select a session and press the OK button.");
  181.         // Enable the OK button.
  182.         GetDlgItem(IDOK)->EnableWindow(TRUE);
  183.         GetDlgItem(IDOK)->SetFocus();
  184.         SetDefID(IDOK);
  185.         // Set the selection on the first session.
  186.         m_ListBox.SetCurSel(0);
  187.         // If we can join the first found - exit dialog.
  188.         if (!g_bEnumAll)
  189.         {
  190.             OnOK();
  191.             return;
  192.         }
  193.     }
  194. }
  195. void
  196. CEnumSession::EmptyListBox()
  197. {
  198.     for (int i = 0; i < m_ListBox.GetCount(); i++)
  199.     {
  200.         HGLOBAL hg = GlobalHandle((LPVOID)m_ListBox.GetItemData(0));
  201.         if (hg)
  202.         {
  203.             GlobalUnlock(hg);
  204.             GlobalFree(hg);
  205.         }
  206.         m_ListBox.DeleteString(0);
  207.     }
  208. }