home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Game Programming for Teens / VBGPFT.cdr / DirectX8 / dx8vbsdk.exe / samples / multimedia / vbsamples / common / dplaycon.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  2000-10-11  |  39.8 KB  |  959 lines

  1. VERSION 5.00
  2. Begin VB.Form DPlayConnect 
  3.    BorderStyle     =   3  'Fixed Dialog
  4.    Caption         =   "Multiplayer connect"
  5.    ClientHeight    =   3330
  6.    ClientLeft      =   45
  7.    ClientTop       =   330
  8.    ClientWidth     =   6345
  9.    Icon            =   "DplayCon.frx":0000
  10.    LinkTopic       =   "Form1"
  11.    MaxButton       =   0   'False
  12.    MinButton       =   0   'False
  13.    ScaleHeight     =   3330
  14.    ScaleWidth      =   6345
  15.    StartUpPosition =   3  'Windows Default
  16.    Begin VB.Frame fraWiz 
  17.       BorderStyle     =   0  'None
  18.       Height          =   3195
  19.       Index           =   1
  20.       Left            =   120
  21.       TabIndex        =   5
  22.       Top             =   60
  23.       Width           =   6195
  24.       Begin VB.CommandButton cmdCancelGame 
  25.          Caption         =   "Cancel"
  26.          Height          =   315
  27.          Left            =   5040
  28.          TabIndex        =   12
  29.          Top             =   2880
  30.          Width           =   1095
  31.       End
  32.       Begin VB.CommandButton cmdRefresh 
  33.          Caption         =   "S&tart Search"
  34.          Height          =   315
  35.          Left            =   5040
  36.          TabIndex        =   11
  37.          Top             =   60
  38.          Width           =   1095
  39.       End
  40.       Begin VB.CommandButton cmdJoin 
  41.          Caption         =   "&Join"
  42.          Height          =   315
  43.          Left            =   60
  44.          TabIndex        =   8
  45.          Top             =   2880
  46.          Width           =   1095
  47.       End
  48.       Begin VB.CommandButton cmdCreate 
  49.          Caption         =   "&Create"
  50.          Height          =   315
  51.          Left            =   1200
  52.          TabIndex        =   7
  53.          Top             =   2880
  54.          Width           =   1095
  55.       End
  56.       Begin VB.ListBox lstGames 
  57.          Height          =   2400
  58.          Left            =   60
  59.          TabIndex        =   6
  60.          Top             =   420
  61.          Width           =   6075
  62.       End
  63.       Begin VB.Label Label3 
  64.          BackStyle       =   0  'Transparent
  65.          Caption         =   "Click 'Start Search' to look for a session, or create one of your own."
  66.          Height          =   255
  67.          Left            =   60
  68.          TabIndex        =   25
  69.          Top             =   120
  70.          Width           =   4935
  71.       End
  72.    End
  73.    Begin VB.Frame fraWiz 
  74.       BorderStyle     =   0  'None
  75.       Height          =   3195
  76.       Index           =   2
  77.       Left            =   120
  78.       TabIndex        =   13
  79.       Top             =   60
  80.       Width           =   6195
  81.       Begin VB.Frame Frame1 
  82.          Caption         =   "Extra Session Options"
  83.          Height          =   1995
  84.          Left            =   60
  85.          TabIndex        =   20
  86.          Top             =   660
  87.          Width           =   5955
  88.          Begin VB.CheckBox chkMigrate 
  89.             Alignment       =   1  'Right Justify
  90.             Caption         =   "Migrate &Host"
  91.             Height          =   255
  92.             Left            =   30
  93.             TabIndex        =   21
  94.             Top             =   600
  95.             Width           =   2895
  96.          End
  97.          Begin VB.TextBox txtUsers 
  98.             Height          =   285
  99.             Left            =   2490
  100.             TabIndex        =   19
  101.             Top             =   240
  102.             Width           =   435
  103.          End
  104.          Begin VB.Label Label1 
  105.             BackStyle       =   0  'Transparent
  106.             Caption         =   "N&umber of players in this session:"
  107.             Height          =   255
  108.             Index           =   2
  109.             Left            =   60
  110.             TabIndex        =   18
  111.             Top             =   285
  112.             Width           =   2355
  113.          End
  114.       End
  115.       Begin VB.TextBox txtGameName 
  116.          Height          =   285
  117.          Left            =   60
  118.          TabIndex        =   17
  119.          Top             =   300
  120.          Width           =   6075
  121.       End
  122.       Begin VB.CommandButton cmdOkCreate 
  123.          Caption         =   "OK"
  124.          Height          =   315
  125.          Left            =   5040
  126.          TabIndex        =   15
  127.          Top             =   2760
  128.          Width           =   1095
  129.       End
  130.       Begin VB.CommandButton cmdCancelCreate 
  131.          Caption         =   "Cancel"
  132.          Height          =   315
  133.          Left            =   3900
  134.          TabIndex        =   14
  135.          Top             =   2760
  136.          Width           =   1095
  137.       End
  138.       Begin VB.Label Label1 
  139.          BackStyle       =   0  'Transparent
  140.          Caption         =   "Please enter the session &name"
  141.          Height          =   255
  142.          Index           =   3
  143.          Left            =   60
  144.          TabIndex        =   16
  145.          Top             =   60
  146.          Width           =   2235
  147.       End
  148.    End
  149.    Begin VB.Timer tmrExpire 
  150.       Interval        =   500
  151.       Left            =   7500
  152.       Top             =   780
  153.    End
  154.    Begin VB.Frame fraWiz 
  155.       BorderStyle     =   0  'None
  156.       Height          =   3195
  157.       Index           =   3
  158.       Left            =   60
  159.       TabIndex        =   22
  160.       Top             =   60
  161.       Width           =   6195
  162.       Begin VB.CommandButton cmdCancelLobby 
  163.          Caption         =   "Cancel"
  164.          Height          =   315
  165.          Left            =   2340
  166.          TabIndex        =   24
  167.          Top             =   1500
  168.          Width           =   1455
  169.       End
  170.       Begin VB.Label Label2 
  171.          BackStyle       =   0  'Transparent
  172.          Caption         =   "Waiting for lobby connection"
  173.          Height          =   375
  174.          Left            =   2100
  175.          TabIndex        =   23
  176.          Top             =   1140
  177.          Width           =   2115
  178.       End
  179.    End
  180.    Begin VB.Frame fraWiz 
  181.       BorderStyle     =   0  'None
  182.       Height          =   3195
  183.       Index           =   0
  184.       Left            =   120
  185.       TabIndex        =   2
  186.       Top             =   60
  187.       Width           =   6195
  188.       Begin VB.CommandButton cmdCancel 
  189.          Cancel          =   -1  'True
  190.          Caption         =   "Cancel"
  191.          Height          =   315
  192.          Left            =   3900
  193.          TabIndex        =   10
  194.          Top             =   2760
  195.          Width           =   1095
  196.       End
  197.       Begin VB.CommandButton cmdOk 
  198.          Caption         =   "OK"
  199.          Default         =   -1  'True
  200.          Height          =   315
  201.          Left            =   5040
  202.          TabIndex        =   9
  203.          Top             =   2760
  204.          Width           =   1095
  205.       End
  206.       Begin VB.ListBox lstSP 
  207.          Height          =   1815
  208.          Left            =   60
  209.          TabIndex        =   4
  210.          Top             =   900
  211.          Width           =   6075
  212.       End
  213.       Begin VB.TextBox txtUserName 
  214.          Height          =   285
  215.          Left            =   60
  216.          TabIndex        =   1
  217.          Top             =   300
  218.          Width           =   6075
  219.       End
  220.       Begin VB.Label Label1 
  221.          BackStyle       =   0  'Transparent
  222.          Caption         =   "Select your ser&vice provider:"
  223.          Height          =   255
  224.          Index           =   1
  225.          Left            =   60
  226.          TabIndex        =   3
  227.          Top             =   660
  228.          Width           =   3915
  229.       End
  230.       Begin VB.Label Label1 
  231.          BackStyle       =   0  'Transparent
  232.          Caption         =   "&Player Name:"
  233.          Height          =   255
  234.          Index           =   0
  235.          Left            =   60
  236.          TabIndex        =   0
  237.          Top             =   60
  238.          Width           =   3915
  239.       End
  240.    End
  241. Attribute VB_Name = "DPlayConnect"
  242. Attribute VB_GlobalNameSpace = False
  243. Attribute VB_Creatable = False
  244. Attribute VB_PredeclaredId = True
  245. Attribute VB_Exposed = False
  246. Option Explicit
  247. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  248. '  Copyright (C) 2000 Microsoft Corporation.  All Rights Reserved.
  249. '  File:       DPlayCon.frm
  250. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  251. 'Sleep declare
  252. Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
  253. 'GetTickCount declare
  254. Private Declare Function GetTickCount Lib "kernel32" () As Long
  255. 'Declares for closing the form without waiting
  256. Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  257. Private Const WM_CLOSE = &H10
  258. 'Host expire threshold constant
  259. Private Const HOST_EXPIRE_THRESHHOLD As Long = 2000
  260. Private Type HostFound
  261.     AppDesc As DPN_APPLICATION_DESC
  262.     Address As String
  263.     TimeLastFound As Long
  264. End Type
  265. Private Enum WizPanes
  266.     PickProtocol
  267.     CreateJoinGame
  268.     CreateNewGame
  269.     WaitForLobby
  270. End Enum
  271. Private Enum SearchingButton
  272.     StartSearch
  273.     StopSearch
  274. End Enum
  275. 'Internal DirectX variables
  276. Private moDPP As DirectPlay8Peer
  277. Private moDPC As DirectPlay8Client
  278. Private moDPA As DirectPlay8Address
  279. Private moDX As DirectX8
  280. Private moCallback As DirectPlay8Event
  281. Private moDPLA As DirectPlay8LobbiedApplication
  282. 'App specific vars
  283. Private msGuid As String
  284. Private sUser As String
  285. Private mlSearch As SearchingButton
  286. Private sGameName As String
  287. Private mlMax As Long
  288. Private mlNumPlayers As Long
  289. Private mfComplete As Boolean
  290. Private mfHost As Boolean
  291. Private mlEnumAsync As Long
  292. Private mfGotEvent As Boolean
  293. Private mfDoneWiz As Boolean
  294. Private mlLobbyClientID As Long
  295. Private mfCanUnload As Boolean
  296. 'We need to keep track of the hosts we get
  297. Private moHosts() As HostFound
  298. Private mlHostCount As Long
  299. 'Declaration for our API
  300. Private Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
  301. Private mfDoneEnum As Boolean
  302. Private mfConnectComplete As Boolean
  303. 'We need to implement the Event model for DirectPlay so we can receive callbacks
  304. Implements DirectPlay8Event
  305. Implements DirectPlay8LobbyEvent
  306. Private Function StartWizard(oDX As DirectX8, sGuid As String, ByVal lMaxPlayers As Long, Optional oCallback As DirectPlay8Event = Nothing, Optional ByVal fAllowMigrateHost As Boolean = True) As Boolean
  307.     Dim lCount As Long
  308.     Dim dpn As DPN_SERVICE_PROVIDER_INFO
  309.     'Now we can start our connection
  310.     mfCanUnload = False
  311.     mlSearch = StartSearch
  312.     mlHostCount = -1
  313.     'First we need to keep track of our Peer Object, and app guid
  314.     Set moDX = oDX
  315.     Set moCallback = oCallback
  316.     msGuid = sGuid
  317.     mlMax = lMaxPlayers
  318.     If Not (moDPP Is Nothing) Then
  319.         moDPP.RegisterMessageHandler Me
  320.         'First load our list of Service Providers into our box
  321.         For lCount = 1 To moDPP.GetCountServiceProviders
  322.             dpn = moDPP.GetServiceProvider(lCount)
  323.             lstSP.AddItem dpn.Name
  324.             'Pick the TCP/IP connection by default
  325.             If InStr(dpn.Name, "TCP") Then lstSP.ListIndex = lstSP.ListCount - 1
  326.         Next
  327.         If lstSP.ListIndex < 0 Then lstSP.ListIndex = 0
  328.     ElseIf Not (moDPC Is Nothing) Then
  329.         moDPC.RegisterMessageHandler Me
  330.         'First load our list of Service Providers into our box
  331.         For lCount = 1 To moDPC.GetCountServiceProviders
  332.             dpn = moDPC.GetServiceProvider(lCount)
  333.             lstSP.AddItem dpn.Name
  334.             'Pick the TCP/IP connection by default
  335.             If InStr(dpn.Name, "TCP") Then lstSP.ListIndex = lstSP.ListCount - 1
  336.         Next
  337.         If lstSP.ListIndex < 0 Then lstSP.ListIndex = 0
  338.     End If
  339.     lstSP.AddItem "Wait for Lobby Connection..."
  340.     'Load the default Username for VBDirectPlay samples
  341.     sUser = GetSetting("VBDirectPlay", "Defaults", "UserName", vbNullString)
  342.     If sUser = vbNullString Then
  343.         'If there is not a default username, then pick the currently
  344.         'logged on username
  345.         sUser = Space$(255)
  346.         GetUserName sUser, 255
  347.         sUser = Left$(sUser, InStr(sUser, Chr$(0)) - 1)
  348.     End If
  349.     chkMigrate.Visible = fAllowMigrateHost
  350.     txtUserName.Text = sUser
  351.     ShowPane PickProtocol
  352.     Set moDPLA = dx.DirectPlayLobbiedApplicationCreate
  353.     'Init the register handler here
  354.     moDPLA.RegisterMessageHandler Me
  355.     'Register this app (in case it isn't registered already)
  356.     RegisterThisApp sGuid
  357.     'Show this screen
  358.     Me.Show vbModeless
  359.     'We have this loop here rather than just displaying the form as a modal
  360.     'dialog if we did just display the form as modal, it would not get a
  361.     'button in the toolbar, since it would have a parent window that wasn't visible
  362.     'By displaying the window modeless, and going into a loop we get to have our
  363.     'icon on the taskbar, and keep the main form waiting until we are done in this form.
  364.     Do While Not mfDoneWiz
  365.         DoSleep 5 'Give other threads cpu time
  366.     Loop
  367.     'Get rid of the lobby interface if it isn't necessary
  368.     If mlLobbyClientID <> 0 Then
  369.         If Not (moDPP Is Nothing) Then
  370.             moDPP.RegisterLobby mlLobbyClientID, moDPLA, DPNLOBBY_UNREGISTER
  371.         ElseIf Not (moDPC Is Nothing) Then
  372.             moDPC.RegisterLobby mlLobbyClientID, moDPLA, DPNLOBBY_UNREGISTER
  373.         End If
  374.     End If
  375.     If Not (moDPLA Is Nothing) Then moDPLA.Close
  376.     Set moDPLA = Nothing
  377.     'Now we can return our success (or failure)
  378.     StartWizard = mfComplete
  379. End Function
  380. Public Function StartClientConnectWizard(oDX As DirectX8, oDPC As DirectPlay8Client, sGuid As String, ByVal lMaxPlayers As Long, Optional oCallback As DirectPlay8Event = Nothing, Optional ByVal fAllowMigrateHost As Boolean = True) As Boolean
  381.     Set moDPP = Nothing
  382.     Set moDPC = oDPC
  383.     cmdCreate.Visible = False
  384.     StartClientConnectWizard = StartWizard(oDX, sGuid, lMaxPlayers, oCallback, fAllowMigrateHost)
  385. End Function
  386. Public Function StartConnectWizard(oDX As DirectX8, oDPP As DirectPlay8Peer, sGuid As String, ByVal lMaxPlayers As Long, Optional oCallback As DirectPlay8Event = Nothing, Optional ByVal fAllowMigrateHost As Boolean = True) As Boolean
  387.     Set moDPC = Nothing
  388.     Set moDPP = oDPP
  389.     cmdCreate.Visible = True
  390.     StartConnectWizard = StartWizard(oDX, sGuid, lMaxPlayers, oCallback, fAllowMigrateHost)
  391. End Function
  392. Public Sub CloseForm(oForm As Form)
  393.     'Anytime we need to close a form from within a DirectPlay callback
  394.     'we need to use this function.  The reason is that DirectPlay uses multiple
  395.     'threads to spawn all of it's messages back to the application.  However
  396.     'it cannot close down until all of it's threads have returned.
  397.     'If we attempt to simply call Unload Me in the callback, we will run into
  398.     'a deadlock instance, since the callback will be running on the DirectPlay
  399.     'thread waiting for the unload to finish, and the unload will be waiting
  400.     'for the DirectPlay thread to finish.
  401.     'PostMessage puts the message on the queue for our form and returns immediately
  402.     'allowing the thread to finish
  403.     PostMessage oForm.hwnd, WM_CLOSE, 0, 0
  404. End Sub
  405. Public Sub DoSleep(Optional ByVal lMilliSec As Long = 0)
  406.     'The DoSleep function allows other threads to have a time slice
  407.     'and still keeps the main VB thread alive (since DPlay callbacks
  408.     'run on separate threads outside of VB).
  409.     Sleep lMilliSec
  410.     DoEvents
  411. End Sub
  412. Private Sub cmdCancel_Click()
  413.     Unload Me
  414. End Sub
  415. Private Sub cmdCancelCreate_Click()
  416.     'If they click cancel here, just go back to the last step
  417.     ShowPane CreateJoinGame
  418. End Sub
  419. Private Sub cmdCancelGame_Click()
  420.     'If they click cancel here, just go back to the first step
  421.     ShowPane PickProtocol
  422. End Sub
  423. Private Sub cmdCancelLobby_Click()
  424.     'Don't wait any more.
  425.     moDPLA.SetAppAvailable False, 0
  426.     ShowPane PickProtocol
  427. End Sub
  428. Private Sub cmdCreate_Click()
  429.     Dim sDefault As String
  430.     'Here we should get our default
  431.     sDefault = GetSetting("VBDirectPlay", "Defaults", "GameName", vbNullString)
  432.     txtGameName.Text = sDefault
  433.     txtUsers.Text = CStr(mlMax)
  434.     chkMigrate.Value = Val(GetSetting("VBDirectPlay", "Defaults", "HostMigrate"))
  435.     'Show the create game screen
  436.     ShowPane CreateNewGame
  437. End Sub
  438. Private Sub cmdJoin_Click()
  439.     Dim HostAddr As DirectPlay8Address
  440.     Dim dpApp As DPN_APPLICATION_DESC
  441.     'You must select a game before you try to join one
  442.     If lstGames.ListIndex < 0 Then
  443.         MsgBox "You must first select a game from the list to join.", vbOKOnly Or vbInformation, "Select game."
  444.         Exit Sub
  445.     End If
  446.     'We no longer need to Enum since we're connecting now
  447.     If mlEnumAsync <> 0 Then cmdRefresh_Click
  448.     'Lets join the game
  449.     Dim pInfo As DPN_PLAYER_INFO
  450.     'Set up my peer info
  451.     pInfo.Name = sUser
  452.     pInfo.lInfoFlags = DPNINFO_NAME
  453.     If Not (moDPP Is Nothing) Then
  454.         moDPP.SetPeerInfo pInfo, DPNOP_SYNC
  455.     ElseIf Not (moDPC Is Nothing) Then
  456.         moDPC.SetClientInfo pInfo, DPNOP_SYNC
  457.     End If
  458.     mfDoneEnum = True
  459.     With moHosts(lstGames.ItemData(lstGames.ListIndex)).AppDesc
  460.         dpApp.guidApplication = .guidApplication
  461.         dpApp.guidInstance = .guidInstance
  462.         mlNumPlayers = .lMaxPlayers
  463.     End With
  464.     mfGotEvent = False
  465.     mfConnectComplete = False
  466.     'Lets get our host address
  467.     Set HostAddr = moDX.DirectPlayAddressCreate
  468.     HostAddr.BuildFromURL moHosts(lstGames.ItemData(lstGames.ListIndex)).Address
  469.     If Not (moDPP Is Nothing) Then
  470.         'Now we can join the selected session
  471.         moDPP.Connect dpApp, HostAddr, moDPA, 0, ByVal 0&, 0
  472.     ElseIf Not (moDPC Is Nothing) Then
  473.         'Now we can join the selected session
  474.         moDPC.Connect dpApp, HostAddr, moDPA, 0, ByVal 0&, 0
  475.     End If
  476.     Do While Not mfGotEvent 'Let's wait for our connectcomplete event
  477.         DoSleep 5 'Give other threads cpu time
  478.     Loop
  479.     If mfConnectComplete Then
  480.         'We've joined our game
  481.         mfComplete = True
  482.         mfHost = False
  483.         'Clean up our address
  484.         Set moDPA = Nothing
  485.         Unload Me
  486.     End If
  487. End Sub
  488. Private Sub cmdOk_Click()
  489.     'They must specify a user name before we continue on to the next step
  490.     If txtUserName.Text = vbNullString Then
  491.         MsgBox "Please enter a username before going on.", vbOKOnly Or vbInformation, "No username"
  492.         Exit Sub
  493.     End If
  494.     sUser = txtUserName.Text
  495.     'Save the username
  496.     SaveSetting "VBDirectPlay", "Defaults", "UserName", sUser
  497.     If lstSP.ListIndex = lstSP.ListCount - 1 Then 'We want to wait for a lobby connection
  498.         moDPLA.SetAppAvailable True, 0
  499.         ShowPane WaitForLobby
  500.     Else
  501.         'Set up the address
  502.         Set moDPA = moDX.DirectPlayAddressCreate
  503.         If Not (moDPP Is Nothing) Then
  504.             moDPA.SetSP moDPP.GetServiceProvider(lstSP.ListIndex + 1).Guid
  505.         ElseIf Not (moDPC Is Nothing) Then
  506.             moDPA.SetSP moDPC.GetServiceProvider(lstSP.ListIndex + 1).Guid
  507.         End If
  508.         'Switch to the next screen
  509.         ShowPane CreateJoinGame
  510.     End If
  511. End Sub
  512. Private Sub cmdOkCreate_Click()
  513.     sGameName = txtGameName.Text
  514.     If sGameName = vbNullString Then
  515.         MsgBox "You must enter a session name to create a session.", vbOKOnly Or vbInformation, "No name."
  516.         Exit Sub 'No need to continue
  517.     End If
  518.     If Val(txtUsers.Text) < 1 Then
  519.         MsgBox "You must enter a number of max players.", vbOKOnly Or vbInformation, "No max players."
  520.         Exit Sub 'No need to continue
  521.     End If
  522.     If Val(txtUsers.Text) > mlMax Then
  523.         MsgBox "The number of maximum players you specified exceeds the number of maximum players allowed in this session." & vbCrLf & "Please lower the number of your maximum players.", vbOKOnly Or vbInformation, "Too many players."
  524.         Exit Sub 'No need to continue
  525.     End If
  526.     mfHost = True
  527.     SaveSetting "VBDirectPlay", "Defaults", "GameName", sGameName
  528.     SaveSetting "VBDirectPlay", "Defaults", "HostMigrate", CStr(chkMigrate.Value)
  529.     If Not chkMigrate.Visible Then chkMigrate.Value = vbUnchecked
  530.     If Not CreateGame(sGameName, (chkMigrate.Value = vbChecked), Val(txtUsers.Text)) Then
  531.         MsgBox "Unable to create session", vbCritical Or vbOKOnly, "No session"
  532.         mfHost = False
  533.         ShowPane CreateJoinGame
  534.     Else
  535.         'We've created our game, load our game screen and wait for people to join
  536.         mfComplete = True
  537.         'Clean up our address
  538.         Set moDPA = Nothing
  539.         Unload Me
  540.     End If
  541. End Sub
  542. Private Sub cmdRefresh_Click()
  543.     If mlSearch = StartSearch Then
  544.         'Time to enum our hosts
  545.         mfDoneEnum = False
  546.         Dim Desc As DPN_APPLICATION_DESC
  547.         Desc.guidApplication = msGuid
  548.         Dim dph As DirectPlay8Address
  549.         
  550.         Set dph = moDX.DirectPlayAddressCreate
  551.         If Not (moDPP Is Nothing) Then
  552.             dph.SetSP moDPP.GetServiceProvider(lstSP.ListIndex + 1).Guid
  553.         ElseIf Not (moDPC Is Nothing) Then
  554.             dph.SetSP moDPC.GetServiceProvider(lstSP.ListIndex + 1).Guid
  555.         End If
  556.         
  557.         If Not (moDPP Is Nothing) Then
  558.             mlEnumAsync = moDPP.EnumHosts(Desc, dph, moDPA, INFINITE, 0, INFINITE, DPNENUMHOSTS_OKTOQUERYFORADDRESSING, ByVal 0&, 0)
  559.         ElseIf Not (moDPC Is Nothing) Then
  560.             mlEnumAsync = moDPC.EnumHosts(Desc, dph, moDPA, INFINITE, 0, INFINITE, DPNENUMHOSTS_OKTOQUERYFORADDRESSING, ByVal 0&, 0)
  561.         End If
  562.         cmdRefresh.Caption = "Stop Search"
  563.         mlSearch = StopSearch
  564.     ElseIf mlSearch = StopSearch Then
  565.         mfDoneEnum = True
  566.         If Not (moDPP Is Nothing) Then
  567.             If mlEnumAsync <> 0 Then moDPP.CancelAsyncOperation mlEnumAsync, 0
  568.         ElseIf Not (moDPC Is Nothing) Then
  569.             If mlEnumAsync <> 0 Then moDPC.CancelAsyncOperation mlEnumAsync, 0
  570.         End If
  571.         cmdRefresh.Caption = "Start Search"
  572.         mlSearch = StartSearch
  573.     End If
  574. End Sub
  575. Private Sub AddHostsToListBox(oHost As DPNMSG_ENUM_HOSTS_RESPONSE)
  576.     Dim lFound As Long
  577.     'Here we will add a host that was found to our list box (or ignore it
  578.     'if it's already been added)
  579.     If mfDoneEnum Then Exit Sub
  580.     If mlHostCount = -1 Then
  581.         'We have no hosts already. Clear our list, and add this one to the list.
  582.         lstGames.Clear
  583.         ReDim moHosts(0)
  584.         moHosts(0).AppDesc = oHost.ApplicationDescription
  585.         moHosts(0).Address = oHost.AddressSenderUrl
  586.         'Save the last time this host was found
  587.         moHosts(0).TimeLastFound = GetTickCount
  588.         With oHost.ApplicationDescription
  589.             lstGames.AddItem .SessionName & " - " & CStr(.lCurrentPlayers) & "/" & CStr(.lMaxPlayers) & " - Latency:" & CStr(oHost.lRoundTripLatencyMS) & " ms"
  590.         End With
  591.         lstGames.ItemData(0) = 0
  592.         mlHostCount = mlHostCount + 1
  593.     Else
  594.         Dim lCount As Long
  595.         Dim fFound As Boolean
  596.         
  597.         For lCount = 0 To mlHostCount
  598.             If moHosts(lCount).AppDesc.guidInstance = oHost.ApplicationDescription.guidInstance Then
  599.                 'Save the last time this host was found
  600.                 moHosts(lCount).TimeLastFound = GetTickCount
  601.                 fFound = True
  602.                 Exit For
  603.             End If
  604.         Next
  605.         
  606.         If Not fFound Then 'We need to add this to the list
  607.             ReDim Preserve moHosts(mlHostCount + 1)
  608.             moHosts(mlHostCount + 1).AppDesc = oHost.ApplicationDescription
  609.             moHosts(mlHostCount + 1).Address = oHost.AddressSenderUrl
  610.             With oHost.ApplicationDescription
  611.                 lstGames.AddItem .SessionName & " - " & CStr(.lCurrentPlayers) & "/" & CStr(.lMaxPlayers) & " - Latency:" & CStr(oHost.lRoundTripLatencyMS) & " ms"
  612.             End With
  613.             'Save the last time this host was found
  614.             moHosts(mlHostCount + 1).TimeLastFound = GetTickCount
  615.             lstGames.ItemData(lstGames.ListCount - 1) = mlHostCount + 1
  616.             mlHostCount = mlHostCount + 1
  617.         Else 'We did find it, update the list
  618.             For lFound = 0 To lstGames.ListCount - 1
  619.                 With oHost.ApplicationDescription
  620.                 If lstGames.ItemData(lFound) = lCount Then 'This is it
  621.                     lstGames.List(lFound) = .SessionName & " - " & CStr(.lCurrentPlayers) & "/" & CStr(.lMaxPlayers) & " - Latency:" & CStr(oHost.lRoundTripLatencyMS) & " ms"
  622.                 End If
  623.                 End With
  624.             Next
  625.         End If
  626.     End If
  627. End Sub
  628. 'We will handle all of the msgs here, and report them all back to the callback sub
  629. 'in case the caller cares what's going on
  630. Private Sub DirectPlay8Event_AddRemovePlayerGroup(ByVal lMsgID As Long, ByVal lPlayerID As Long, ByVal lGroupID As Long, fRejectMsg As Boolean)
  631.     'VB requires that we must implement *every* member of this interface
  632.     If (Not moCallback Is Nothing) Then moCallback.AddRemovePlayerGroup lMsgID, lPlayerID, lGroupID, fRejectMsg
  633. End Sub
  634. Private Sub DirectPlay8Event_AppDesc(fRejectMsg As Boolean)
  635.     'VB requires that we must implement *every* member of this interface
  636.     If (Not moCallback Is Nothing) Then moCallback.AppDesc fRejectMsg
  637. End Sub
  638. Private Sub DirectPlay8Event_AsyncOpComplete(dpnotify As DxVBLibA.DPNMSG_ASYNC_OP_COMPLETE, fRejectMsg As Boolean)
  639.     If dpnotify.AsyncOpHandle = mlEnumAsync Then mlEnumAsync = 0
  640.     'VB requires that we must implement *every* member of this interface
  641.     If (Not moCallback Is Nothing) Then moCallback.AsyncOpComplete dpnotify, fRejectMsg
  642. End Sub
  643. Private Sub DirectPlay8Event_ConnectComplete(dpnotify As DxVBLibA.DPNMSG_CONNECT_COMPLETE, fRejectMsg As Boolean)
  644.     mfGotEvent = True
  645.     If dpnotify.hResultCode = DPNERR_SESSIONFULL Then 'Already too many people joined up
  646.         MsgBox "The maximum number of people allowed in this session have already joined.  Please choose a different session or create your own.", vbOKOnly Or vbInformation, "Full"
  647.         ShowPane CreateJoinGame
  648.     Else
  649.         'We got our connect complete event
  650.         mfConnectComplete = True
  651.         'VB requires that we must implement *every* member of this interface
  652.         If (Not moCallback Is Nothing) Then moCallback.ConnectComplete dpnotify, fRejectMsg
  653.     End If
  654. End Sub
  655. Private Sub DirectPlay8Event_CreateGroup(ByVal lGroupID As Long, ByVal lOwnerID As Long, fRejectMsg As Boolean)
  656.     'VB requires that we must implement *every* member of this interface
  657.     If (Not moCallback Is Nothing) Then moCallback.CreateGroup lGroupID, lOwnerID, fRejectMsg
  658. End Sub
  659. Private Sub DirectPlay8Event_CreatePlayer(ByVal lPlayerID As Long, fRejectMsg As Boolean)
  660.     'VB requires that we must implement *every* member of this interface
  661.     If (Not moCallback Is Nothing) Then moCallback.CreatePlayer lPlayerID, fRejectMsg
  662. End Sub
  663. Private Sub DirectPlay8Event_DestroyGroup(ByVal lGroupID As Long, ByVal lReason As Long, fRejectMsg As Boolean)
  664.     'VB requires that we must implement *every* member of this interface
  665.     If (Not moCallback Is Nothing) Then moCallback.DestroyGroup lGroupID, lReason, fRejectMsg
  666. End Sub
  667. Private Sub DirectPlay8Event_DestroyPlayer(ByVal lPlayerID As Long, ByVal lReason As Long, fRejectMsg As Boolean)
  668.     'VB requires that we must implement *every* member of this interface
  669.     If (Not moCallback Is Nothing) Then moCallback.DestroyPlayer lPlayerID, lReason, fRejectMsg
  670. End Sub
  671. Private Sub DirectPlay8Event_EnumHostsQuery(dpnotify As DxVBLibA.DPNMSG_ENUM_HOSTS_QUERY, fRejectMsg As Boolean)
  672.     'VB requires that we must implement *every* member of this interface
  673.     If (Not moCallback Is Nothing) Then moCallback.EnumHostsQuery dpnotify, fRejectMsg
  674. End Sub
  675. Private Sub DirectPlay8Event_EnumHostsResponse(dpnotify As DxVBLibA.DPNMSG_ENUM_HOSTS_RESPONSE, fRejectMsg As Boolean)
  676.     'Go ahead and add this to our list
  677.     AddHostsToListBox dpnotify
  678.     'VB requires that we must implement *every* member of this interface
  679.     If (Not moCallback Is Nothing) Then moCallback.EnumHostsResponse dpnotify, fRejectMsg
  680. End Sub
  681. Private Sub DirectPlay8Event_HostMigrate(ByVal lNewHostID As Long, fRejectMsg As Boolean)
  682.     'VB requires that we must implement *every* member of this interface
  683.     If (Not moCallback Is Nothing) Then moCallback.HostMigrate lNewHostID, fRejectMsg
  684. End Sub
  685. Private Sub DirectPlay8Event_IndicateConnect(dpnotify As DxVBLibA.DPNMSG_INDICATE_CONNECT, fRejectMsg As Boolean)
  686.     'VB requires that we must implement *every* member of this interface
  687.     If (Not moCallback Is Nothing) Then moCallback.IndicateConnect dpnotify, fRejectMsg
  688. End Sub
  689. Private Sub DirectPlay8Event_IndicatedConnectAborted(fRejectMsg As Boolean)
  690.     'VB requires that we must implement *every* member of this interface
  691.     If (Not moCallback Is Nothing) Then moCallback.IndicatedConnectAborted fRejectMsg
  692. End Sub
  693. Private Sub DirectPlay8Event_InfoNotify(ByVal lMsgID As Long, ByVal lNotifyID As Long, fRejectMsg As Boolean)
  694.     'VB requires that we must implement *every* member of this interface
  695.     If (Not moCallback Is Nothing) Then moCallback.InfoNotify lMsgID, lNotifyID, fRejectMsg
  696. End Sub
  697. Private Sub DirectPlay8Event_Receive(dpnotify As DxVBLibA.DPNMSG_RECEIVE, fRejectMsg As Boolean)
  698.     'VB requires that we must implement *every* member of this interface
  699.     If (Not moCallback Is Nothing) Then moCallback.Receive dpnotify, fRejectMsg
  700. End Sub
  701. Private Sub DirectPlay8Event_SendComplete(dpnotify As DxVBLibA.DPNMSG_SEND_COMPLETE, fRejectMsg As Boolean)
  702.     'VB requires that we must implement *every* member of this interface
  703.     If (Not moCallback Is Nothing) Then moCallback.SendComplete dpnotify, fRejectMsg
  704. End Sub
  705. Private Sub DirectPlay8Event_TerminateSession(dpnotify As DxVBLibA.DPNMSG_TERMINATE_SESSION, fRejectMsg As Boolean)
  706.     'VB requires that we must implement *every* member of this interface
  707.     If (Not moCallback Is Nothing) Then moCallback.TerminateSession dpnotify, fRejectMsg
  708. End Sub
  709. Private Sub DirectPlay8LobbyEvent_Connect(dlNotify As DxVBLibA.DPL_MESSAGE_CONNECT, fRejectMsg As Boolean)
  710.     Dim oDev As DirectPlay8Address, oHost As DirectPlay8Address
  711.     Dim oSetting As DPL_CONNECTION_SETTINGS
  712.     Dim pInfo As DPN_PLAYER_INFO
  713.     On Local Error GoTo ErrOut
  714.     mlLobbyClientID = dlNotify.ConnectId
  715.     oSetting = moDPLA.GetConnectionSettings(mlLobbyClientID, 0)
  716.     'We were just connected to from a lobby
  717.     With oSetting
  718.     If Not (moDPP Is Nothing) Then
  719.         moDPP.RegisterLobby mlLobbyClientID, moDPLA, DPNLOBBY_REGISTER
  720.     ElseIf Not (moDPC Is Nothing) Then
  721.         moDPC.RegisterLobby mlLobbyClientID, moDPLA, DPNLOBBY_REGISTER
  722.     End If
  723.     'With ConnectionSettings
  724.     If .PlayerName <> vbNullString Then
  725.         sUser = .PlayerName
  726.         'Am I the host
  727.         If (.lFlags And DPLCONNECTSETTINGS_HOST) = DPLCONNECTSETTINGS_HOST Then
  728.             'Get the device address to host on
  729.             Set oDev = moDX.DirectPlayAddressCreate
  730.             oDev.BuildFromURL dlNotify.dplMsgCon.AddressSenderUrl
  731.             If Not CreateGameLobby(oDev, .ApplicationDescription) Then
  732.                 MsgBox "Unable to create session", vbCritical Or vbOKOnly, "No session"
  733.                 mfHost = False
  734.                 ShowPane CreateJoinGame
  735.             Else
  736.                 'We've created our game, load our game screen and wait for people to join
  737.                 mfHost = True 'We are the host
  738.                 mfComplete = True
  739.                 'Clean up our address
  740.                 Set moDPA = Nothing
  741.                 Unload Me
  742.             End If
  743.         Else 'we want to connect to an running app
  744.             sUser = .PlayerName
  745.             'Set up my peer info
  746.             pInfo.Name = sUser
  747.             pInfo.lInfoFlags = DPNINFO_NAME
  748.             'Go ahead and connect
  749.             Set oDev = moDX.DirectPlayAddressCreate
  750.             oDev.BuildFromURL dlNotify.dplMsgCon.AddressSenderUrl
  751.             Set oHost = moDX.DirectPlayAddressCreate
  752.             oHost.BuildFromURL dlNotify.dplMsgCon.AddressDeviceUrl
  753.             If Not (moDPP Is Nothing) Then
  754.                 moDPP.SetPeerInfo pInfo, DPNOP_SYNC
  755.                 'Connect now
  756.                 moDPP.Connect .ApplicationDescription, oHost, oDev, 0, ByVal 0&, 0
  757.             ElseIf Not (moDPC Is Nothing) Then
  758.                 moDPC.SetClientInfo pInfo, DPNOP_SYNC
  759.                 'Connect now
  760.                 moDPC.Connect .ApplicationDescription, oHost, oDev, 0, ByVal 0&, 0
  761.             End If
  762.             'Now we should wait until the connect complete event has fired
  763.             Do While Not mfConnectComplete
  764.                 DoEvents
  765.                 'We need to sleep here since the Directplay callbacks run on separate
  766.                 'threads, and a tight loop with only doevents will not allow them enough
  767.                 'time to call into VB.  Sleep 'pauses' this thread for a short time,
  768.                 'allowing the callbacks to process
  769.                 Sleep 10
  770.             Loop
  771.             'We've joined our game
  772.             mfComplete = True
  773.             mfHost = False
  774.             'Clean up our address
  775.             Set moDPA = Nothing
  776.             Unload Me
  777.             
  778.         End If
  779.     Else
  780.         ShowPane PickProtocol
  781.     End If
  782.     End With
  783.     Exit Sub
  784. ErrOut:
  785.     Debug.Print "Error:" & CStr(Err.Number) & " - " & Err.Description
  786. End Sub
  787. Private Sub DirectPlay8LobbyEvent_ConnectionSettings(ConnectionSettings As DxVBLibA.DPL_MESSAGE_CONNECTION_SETTINGS)
  788.     'VB requires that we must implement *every* member of this interface
  789. End Sub
  790. Private Sub DirectPlay8LobbyEvent_Disconnect(ByVal DisconnectID As Long, ByVal lReason As Long)
  791.     'VB requires that we must implement *every* member of this interface
  792. End Sub
  793. Private Sub DirectPlay8LobbyEvent_Receive(dlNotify As DxVBLibA.DPL_MESSAGE_RECEIVE, fRejectMsg As Boolean)
  794.     'VB requires that we must implement *every* member of this interface
  795. End Sub
  796. Private Sub DirectPlay8LobbyEvent_SessionStatus(ByVal status As Long, ByVal lHandle As Long)
  797.     'VB requires that we must implement *every* member of this interface
  798. End Sub
  799. Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  800.     If Not mfCanUnload Then Cancel = 1
  801.     Me.Hide
  802.     mfDoneWiz = True
  803. End Sub
  804. Private Sub Form_Unload(Cancel As Integer)
  805.     'Clean up our lobbied app
  806.     If Not (moDPLA Is Nothing) Then
  807.         moDPLA.Close
  808.     End If
  809.     Set moDPLA = Nothing
  810.     'Clean up our address
  811.     Set moDPA = Nothing
  812. End Sub
  813. Private Sub lstGames_DblClick()
  814.     cmdJoin_Click
  815. End Sub
  816. Private Function CreateGame(ByVal sGameName As String, ByVal fHostMigrate As Boolean, ByVal lNumPlayers As Long) As Boolean
  817.     On Error GoTo ErrOut
  818.     'We want to host our own game
  819.     Dim pInfo As DPN_PLAYER_INFO
  820.     Dim AppDesc As DPN_APPLICATION_DESC
  821.     'Now set up the app description
  822.     With AppDesc
  823.         .guidApplication = msGuid
  824.         .lMaxPlayers = lNumPlayers
  825.         .SessionName = sGameName
  826.         If fHostMigrate Then
  827.             .lFlags = .lFlags Or DPNSESSION_MIGRATE_HOST
  828.         End If
  829.     End With
  830.     mlNumPlayers = lNumPlayers
  831.     'Set up my peer info
  832.     pInfo.Name = sUser
  833.     pInfo.lInfoFlags = DPNINFO_NAME
  834.     moDPP.SetPeerInfo pInfo, DPNOP_SYNC
  835.     moDPP.Host AppDesc, moDPA
  836.     CreateGame = True
  837.     Exit Function
  838. ErrOut:
  839.     CreateGame = False
  840.     Debug.Print "Error;"; Err; " - "; Err.Description
  841. End Function
  842. Private Sub lstSP_DblClick()
  843.     cmdOk_Click
  844. End Sub
  845. Public Property Get IsHost() As Boolean
  846.     IsHost = mfHost
  847. End Property
  848. Public Property Get SessionName() As String
  849.     SessionName = sGameName
  850. End Property
  851. Public Property Get UserName() As String
  852.     UserName = sUser
  853. End Property
  854. Public Sub GoUnload()
  855.     tmrExpire.Enabled = False
  856.     mfCanUnload = True
  857.     Unload Me
  858. End Sub
  859. Public Sub RegisterCallback(oCallback As DirectPlay8Event)
  860.     Set moCallback = oCallback
  861. End Sub
  862. Public Property Get NumPlayers() As Long
  863.     NumPlayers = mlNumPlayers
  864. End Property
  865. Private Sub ShowPane(ByVal lIndex As WizPanes)
  866.     'Here we will show the correct pane, and do whatever else
  867.     'we might need to do to get the step set up.
  868.     fraWiz(lIndex).ZOrder
  869.     Select Case lIndex
  870.     Case PickProtocol
  871.         cmdOk.Default = True
  872.         cmdCancel.Cancel = True
  873.         Me.Caption = App.EXEName & " - Choose Protocol"
  874.     Case CreateJoinGame
  875.         cmdCancelGame.Cancel = True
  876.         Me.Caption = App.EXEName & " - Create or Join Session"
  877.     Case CreateNewGame
  878.         cmdOkCreate.Default = True
  879.         cmdCancelCreate.Cancel = True
  880.         txtGameName.SetFocus
  881.         Me.Caption = App.EXEName & " - Create Session"
  882.     Case WaitForLobby
  883.         cmdCancelLobby.Cancel = True
  884.         cmdCancelLobby.Default = True
  885.         cmdCancelLobby.SetFocus
  886.         Me.Caption = App.EXEName & " - Wait for lobby connection"
  887.     End Select
  888. End Sub
  889. Private Function CreateGameLobby(oHostAddr As DirectPlay8Address, newDesc As DPN_APPLICATION_DESC) As Boolean
  890.     On Error GoTo ErrOut
  891.     'We want to host our own game
  892.     Dim pInfo As DPN_PLAYER_INFO
  893.     'Set up my peer info
  894.     pInfo.Name = sUser
  895.     pInfo.lInfoFlags = DPNINFO_NAME
  896.     'We are only using the Peer object, since the client object *can't* host a session
  897.     moDPP.SetPeerInfo pInfo, DPNOP_SYNC
  898.     newDesc.lFlags = newDesc.lFlags Or DPNSESSION_MIGRATE_HOST 'Turn on Migrate host by default
  899.     newDesc.lMaxPlayers = mlMax 'Let the max players join
  900.     sGameName = newDesc.SessionName
  901.     moDPP.Host newDesc, oHostAddr
  902.     CreateGameLobby = True
  903.     Exit Function
  904. ErrOut:
  905.     CreateGameLobby = False
  906.     Debug.Print "Error;" & CStr(Err.Number) & " - " & Err.Description
  907. End Function
  908. Private Sub RegisterThisApp(sGuid As String)
  909.     Dim dplProg As DPL_PROGRAM_DESC
  910.     'We need to register this program in case we aren't already registered
  911.     With dplProg
  912.         .ApplicationName = App.EXEName
  913.         .Description = "VB DirectPlay SDK Sample"
  914.         .ExecutableFilename = App.EXEName & ".exe"
  915.         .ExecutablePath = App.Path
  916.         .LauncherFilename = App.EXEName & ".exe"
  917.         .LauncherPath = App.Path
  918.         .guidApplication = sGuid
  919.     End With
  920.     moDPLA.RegisterProgram dplProg, 0
  921. End Sub
  922. Private Sub tmrExpire_Timer()
  923.     'We need to periodically expire the hosts that are in this list in case they are
  924.     'no longer hosting or what have you.
  925.     Dim lCount As Long, lIndex As Long
  926.     Dim lInner As Long
  927.     On Error GoTo LeaveSub 'If there are no hosts, just go
  928.     For lCount = 0 To UBound(moHosts)
  929.         If (GetTickCount - moHosts(lCount).TimeLastFound) > HOST_EXPIRE_THRESHHOLD Then
  930.             'Yup, this guy expired.. remove him from the list
  931.             For lIndex = lstGames.ListCount - 1 To 0 Step -1
  932.                 If lstGames.ItemData(lIndex) = lCount Then 'this is the one
  933.                     lstGames.RemoveItem lIndex
  934.                 End If
  935.             Next
  936.             moHosts(lCount).Address = vbNullString
  937.             'Now we need an internal loop to 'remove' all of the old hosts info
  938.             For lInner = lCount + 1 To UBound(moHosts)
  939.                 moHosts(lInner - 1).Address = moHosts(lInner).Address
  940.                 moHosts(lInner - 1).AppDesc = moHosts(lInner).AppDesc
  941.                 moHosts(lInner - 1).TimeLastFound = moHosts(lInner).TimeLastFound
  942.             Next
  943.             'Now we need to decrement each of the remaining items in the listbox
  944.             For lIndex = lstGames.ListCount - 1 To 0 Step -1
  945.                 If lstGames.ItemData(lIndex) > lCount Then 'decrement this one
  946.                     lstGames.ItemData(lIndex) = lstGames.ItemData(lIndex) - 1
  947.                 End If
  948.             Next
  949.             mlHostCount = mlHostCount - 1
  950.             If UBound(moHosts) > 0 Then
  951.                 ReDim Preserve moHosts(UBound(moHosts) - 1)
  952.             Else
  953.                 Erase moHosts 'This will just erase the memory
  954.             End If
  955.         End If
  956.     Next
  957. LeaveSub:
  958. End Sub
  959.