⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netconnect.cpp

📁 VC游戏编程基础
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        SendMessage( m_hDlg, WM_COMMAND, IDC_SEARCH_CHECK, 0 );
    }

    m_bHostPlayer = TRUE;

    IDirectPlay8Address*   pDP8AddressHost  = NULL;
    WCHAR*                 wszHostName      = NULL;

    // Create the local host address object
    if( FAILED( hr = CoCreateInstance( CLSID_DirectPlay8Address, NULL, 
                                       CLSCTX_ALL, IID_IDirectPlay8Address,
                                       (LPVOID*) &pDP8AddressHost ) ) )
    {
        DXTRACE_ERR_MSGBOX( TEXT("CoCreateInstance"), hr );
        goto LCleanup;
    }

    // Set service provider
    if( FAILED( hr = pDP8AddressHost->SetSP( &m_guidSP ) ) )
    {
        DXTRACE_ERR_MSGBOX( TEXT("SetSP"), hr );
        goto LCleanup;
    }

    // If were are using a service provider that requires a port value, 
    // and the user has requested a particular port number, set that
    // port as a component of the host address. If no port is specified, 
    // DirectPlay will automatically select an open port
    if( m_dwPort != 0 && SPRequiresPort( &m_guidSP ) )
    {
        hr = pDP8AddressHost->AddComponent( DPNA_KEY_PORT, 
                                            &m_dwPort, 
                                            sizeof(m_dwPort),
                                            DPNA_DATATYPE_DWORD );
        if( FAILED(hr) )
        {
            DXTRACE_ERR_MSGBOX( TEXT("AddComponent"), hr );
            goto LCleanup;
        }
    }

    // Set peer info name
    WCHAR wszPeerName[MAX_PLAYER_NAME];
    DXUtil_ConvertGenericStringToWideCch( wszPeerName, m_strLocalPlayerName, MAX_PLAYER_NAME );

    DPN_PLAYER_INFO dpPlayerInfo;
    ZeroMemory( &dpPlayerInfo, sizeof(DPN_PLAYER_INFO) );
    dpPlayerInfo.dwSize = sizeof(DPN_PLAYER_INFO);
    dpPlayerInfo.dwInfoFlags = DPNINFO_NAME;
    dpPlayerInfo.pwszName = wszPeerName;

    // Set the peer info, and use the DPNOP_SYNC since by default this
    // is an async call.  If it is not DPNOP_SYNC, then the peer info may not
    // be set by the time we call Host() below.
    if( FAILED( hr = m_pDP->SetPeerInfo( &dpPlayerInfo, NULL, NULL, DPNOP_SYNC ) ) )
    {
        DXTRACE_ERR_MSGBOX( TEXT("SetPeerInfo"), hr );
        goto LCleanup;
    }

    WCHAR wszSessionName[MAX_PATH];
    DXUtil_ConvertGenericStringToWideCch( wszSessionName, m_strSessionName, MAX_PATH );

    // Setup the application desc
    DPN_APPLICATION_DESC dnAppDesc;
    ZeroMemory( &dnAppDesc, sizeof(DPN_APPLICATION_DESC) );
    dnAppDesc.dwSize          = sizeof(DPN_APPLICATION_DESC);
    dnAppDesc.guidApplication = m_guidApp;
    dnAppDesc.pwszSessionName = wszSessionName;
    dnAppDesc.dwMaxPlayers    = m_dwMaxPlayers;
    dnAppDesc.dwFlags         = 0;
    if( m_bMigrateHost )
        dnAppDesc.dwFlags |= DPNSESSION_MIGRATE_HOST;

    if( !m_bUseDPNSVR )
        dnAppDesc.dwFlags |= DPNSESSION_NODPNSVR;

    if( SIGN_FAST == m_eSigningType )
        dnAppDesc.dwFlags |= DPNSESSION_FAST_SIGNED;
    else if( SIGN_FULL == m_eSigningType )
        dnAppDesc.dwFlags |= DPNSESSION_FULL_SIGNED;

    
    // Host a game on m_pDeviceAddress as described by dnAppDesc
    // DPNHOST_OKTOQUERYFORADDRESSING allows DirectPlay to prompt the user
    // using a dialog box for any device address information that is missing
    if( FAILED( hr = m_pDP->Host( &dnAppDesc,               // the application desc
                                  &pDP8AddressHost,         // array of addresses of the local devices used to connect to the host
                                  1,                        // number in array
                                  NULL, NULL,               // DPN_SECURITY_DESC, DPN_SECURITY_CREDENTIALS
                                  NULL,                     // player context
                                  DPNHOST_OKTOQUERYFORADDRESSING ) ) ) // flags
    { 
        // This error is often caused by a port conflict
        if( hr == DPNERR_INVALIDDEVICEADDRESS && 
            m_dwPort != 0 && SPRequiresPort( &m_guidSP ) )
        {
            MessageBox( hDlg, TEXT("This error is often caused by a port conflict.\n\n")
                              TEXT("If another application is already using the port you specified,\n")
                              TEXT("try creating the game using a different port number."),
                        TEXT("Invalid Device Address"), MB_OK | MB_ICONINFORMATION );
        }

        DXTRACE_ERR_MSGBOX( TEXT("Host"), hr );
        goto LCleanup;
    }

    // DirectPlay connect successful, so end dialog
    m_hrDialog = NCW_S_FORWARD;
    EndDialog( hDlg, 0 );

LCleanup:
    SAFE_RELEASE( pDP8AddressHost );
    SAFE_DELETE( wszHostName );

    return hr;
}




//-----------------------------------------------------------------------------
// Name: StaticConnectionsDlgProc()
// Desc: Static msg handler which passes messages
//-----------------------------------------------------------------------------
INT_PTR CALLBACK CNetConnectWizard::StaticCreateSessionDlgProc( HWND hDlg, UINT uMsg,
                                                                WPARAM wParam, LPARAM lParam )
{
    if( g_pNCW )
        return g_pNCW->CreateSessionDlgProc( hDlg, uMsg, wParam, lParam );

    return FALSE; // Message not handled
}




//-----------------------------------------------------------------------------
// Name: CreateSessionDlgProc()
// Desc: Handles messages fro the multiplayer create game dialog
//-----------------------------------------------------------------------------
INT_PTR CALLBACK CNetConnectWizard::CreateSessionDlgProc( HWND hDlg, UINT msg,
                                                          WPARAM wParam, LPARAM lParam )
{
    UNREFERENCED_PARAMETER( lParam );
    DWORD dwNameLength;

    switch( msg )
    {
        case WM_INITDIALOG:
#if defined(WIN32_PLATFORM_PSPC) && (_WIN32_WCE >= 300)
            SHINITDLGINFO   shidi;
            memset(&shidi, 0, sizeof(SHINITDLGINFO));
            shidi.dwMask = SHIDIM_FLAGS;
            shidi.dwFlags = SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;
            shidi.hDlg = hDlg;

            SetForegroundWindow(hDlg);
            SHInitDialog(&shidi);
#endif // WIN32_PLATFORM_PSPC

            SetDlgItemText( hDlg, IDC_EDIT_SESSION_NAME, m_strSessionName );
            CheckDlgButton( hDlg, IDC_MIGRATE_HOST, BST_CHECKED );
            CheckDlgButton( hDlg, IDC_SIGNING_FAST, BST_CHECKED );

            // Fill in the port value if the calling application gave us a default
            if( m_dwPort != 0 )
            {
                TCHAR strPort[40];
                _itot( m_dwPort, strPort, 10 );
                SetDlgItemText( hDlg, IDC_LOCAL_PORT, strPort );
            }

            // Hide the port field for service providers which don't use it
            if( !SPRequiresPort( &m_guidSP ) )
            {
                ShowWindow( GetDlgItem( hDlg, IDC_LOCAL_PORT ), SW_HIDE );
                ShowWindow( GetDlgItem( hDlg, IDC_LOCAL_PORT_TEXT ), SW_HIDE );
            }
            
            return TRUE;

// Context-sensitive help is not supported on PocketPC
#ifndef UNDER_CE
        case WM_HELP:
            LPHELPINFO lphi;
            lphi = (LPHELPINFO) lParam;

            switch( lphi->iCtrlId )
            {
                case IDC_EDIT_SESSION_NAME:
                    MessageBox( hDlg, TEXT("The name used to help other players identify\n")
                                      TEXT("your session across the network."), 
                                TEXT("Game Name"), MB_OK | MB_ICONQUESTION );
                    break;
                
                case IDC_SIGNING_FULL:
                case IDC_SIGNING_FAST:
                    MessageBox( hDlg, TEXT("The level of cryptographic security to use for\n")
                                      TEXT("network data; full-signing provides the most\n")
                                      TEXT("protection against spoofing at the cost of\n")
                                      TEXT("additional packet size."), 
                                TEXT("Session Signing"), MB_OK | MB_ICONQUESTION );
                    break;

                case IDC_MIGRATE_HOST:
                    MessageBox( hDlg, TEXT("If enabled, DirectPlay will automatically select\n")
                                      TEXT("a new session host if the current host exits."), 
                                TEXT("Host Migration"), MB_OK | MB_ICONQUESTION );
                    break;

                case IDC_USE_DPNSVR:
                    MessageBox( hDlg, TEXT("This DirectPlay-managed application accepts\n")
                                      TEXT("enumeration requests on a known port and forwards\n")
                                      TEXT("incoming requests to all sessions on the machine,\n")
                                      TEXT("which allows the querying player to find sessions\n")
                                      TEXT("without knowing the port address.\n\n")
                                      TEXT("This service may not work properly with certain\n")
                                      TEXT("NAT configurations."), 
                                TEXT("DPNSVR"), MB_OK | MB_ICONQUESTION );
                    break;

                case IDC_LOCAL_PORT:
                    MessageBox( hDlg, TEXT("Specifies the local port on which to host the new\n")
                                      TEXT("session. If set blank, DirectPlay will automatically\n")
                                      TEXT("select an open port."), 
                                TEXT("Local Port"), MB_OK | MB_ICONQUESTION );
                    break;

                default:
                    return FALSE; // Not handled
            }
            return TRUE;
#endif // !UNDER_CE

        case WM_COMMAND:
            switch( LOWORD(wParam) )
            {
                case IDOK:
                    dwNameLength = GetDlgItemText( hDlg, IDC_EDIT_SESSION_NAME,
                                                   m_strSessionName,
                                                   MAX_PATH );
                    if( dwNameLength == 0 )
                        return TRUE; // Don't accept blank session names

                    m_bMigrateHost = ( IsDlgButtonChecked( hDlg,
                                       IDC_MIGRATE_HOST ) == BST_CHECKED );

                    m_bUseDPNSVR = ( IsDlgButtonChecked( hDlg,
                                     IDC_USE_DPNSVR ) == BST_CHECKED );

                    // Set the desired port value
                    TCHAR strPort[40];
                    GetDlgItemText( hDlg, IDC_LOCAL_PORT, strPort, 40 );
                    strPort[39] = 0;

                    m_dwPort = _ttoi( strPort );

                    // Set session signing options
                    if( BST_CHECKED == IsDlgButtonChecked( hDlg, IDC_SIGNING_FAST ) )
                        m_eSigningType = SIGN_FAST;
                    else if( BST_CHECKED == IsDlgButtonChecked( hDlg, IDC_SIGNING_FULL ) )
                        m_eSigningType = SIGN_FULL;
                    else
                        m_eSigningType = SIGN_NONE;

                    EndDialog( hDlg, IDOK );
                    return TRUE;

                case IDCANCEL:
                    EndDialog( hDlg, IDCANCEL );
                    return TRUE;
            }
            break;
    }

    return FALSE; // Didn't handle message
}




//-----------------------------------------------------------------------------
// Name: SessionsDlgEnumListCleanup()
// Desc: Deletes the linked list, g_DPHostEnumInfoHead
//-----------------------------------------------------------------------------
VOID CNetConnectWizard::SessionsDlgEnumListCleanup()
{
    DPHostEnumInfo* pDPHostEnum = m_DPHostEnumHead.pNext;
    DPHostEnumInfo* pDPHostEnumDelete;

    while ( pDPHostEnum != &m_DPHostEnumHead )
    {
        pDPHostEnumDelete = pDPHostEnum;
        pDPHostEnum = pDPHostEnum->pNext;

        if( pDPHostEnumDelete->pAppDesc )
        {
            SAFE_DELETE_ARRAY( pDPHostEnumDelete->pAppDesc->pwszSessionName );
            SAFE_DELETE( pDPHostEnumDelete->pAppDesc );
        }

        // Changed from array delete to Release
        SAFE_RELEASE( pDPHostEnumDelete->pHostAddr );
        SAFE_RELEASE( pDPHostEnumDelete->pDeviceAddr );
        SAFE_DELETE( pDPHostEnumDelete );
    }

    // Re-link the g_DPHostEnumInfoHead circular linked list
    m_DPHostEnumHead.pNext = &m_DPHostEnumHead;
}




//-----------------------------------------------------------------------------
// Name: StaticAddressDlgProc()
// Desc: Static msg handler which passes messages
//-----------------------------------------------------------------------------
INT_PTR CALLBACK CNetConnectWizard::StaticAddressDlgProc( HWND hDlg, UINT uMsg,
                                                          WPARAM wParam, LPARAM lParam )
{
    if( g_pNCW )
        return g_pNCW->AddressDlgProc( hDlg, uMsg, wParam, lParam );

    return FALSE; // Message not handled
}




//-----------------------------------------------------------------------------
// Name: AddressDlgProc()
// Desc: Handles messages for the multiplayer connect dialog
//-----------------------------------------------------------------------------
INT_PTR CALLBACK CNetConnectWizard::AddressDlgProc( HWND hDlg, UINT msg,
                                                    WPARAM wParam, LPARAM lParam )
{
    UNREFERENCED_PARAMETER( lParam );
    
    switch( msg )
    {
        case WM_INITDIALOG:
        {
#if defined(WIN32_PLATFORM_PSPC) && (_WIN32_WCE >= 300)
            SHINITDLGINFO   shidi;
            memset(&shidi, 0, si

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -