CONNECT.C

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright 1993 - 1998 Microsoft Corporation. All Rights Reserved.
//
// MODULE: connect.c
//
// PURPOSE: Displays the "Connect" dialog box
//
// FUNCTIONS:
// CmdConnect - Displays the "Connect" dialog box
// Connect - Processes messages for "Connect" dialog box.
// MsgConnectInit - Initializes edit controls
// MsgConnectCommand - Process WM_COMMAND message sent to the connect box.
// CmdConnectDone - Free the connect box and related data.
// CmdConnectNow - Establishes connection to specified address. Kills
// dialog if successful.
//
// COMMENTS:
//
//

#include <windows.h> // required for all Windows applications
#include <windowsx.h>
#include <wsipx.h> // IPX sockets
#include <stdlib.h>
#include <stdio.h>
#include "globals.h" // prototypes specific to this application

// Function Definitions


LRESULT CALLBACK Connect(HWND, UINT, WPARAM, LPARAM);
LRESULT MsgConnectInit(HWND, UINT, WPARAM, LPARAM);
LRESULT MsgConnectCommand(HWND, UINT, WPARAM, LPARAM);
LRESULT CmdConnectNow(HWND, WORD, WORD, HWND);
LRESULT CmdConnectDone(HWND, WORD, WORD, HWND);

// Connect dialog message table definition.
MSD rgmsdConnect[] =
{
{WM_COMMAND, MsgConnectCommand},
{WM_INITDIALOG, MsgConnectInit}
};

MSDI msdiConnect =
{
sizeof(rgmsdConnect) / sizeof(MSD),
rgmsdConnect,
edwpNone
};

// Connect dialog command table definition.
CMD rgcmdConnect[] =
{
{IDOK, CmdConnectNow},
{IDCANCEL, CmdConnectDone}
};

CMDI cmdiConnect =
{
sizeof(rgcmdConnect) / sizeof(CMD),
rgcmdConnect,
edwpNone
};

// Module specific "globals" Used when a variable needs to be
// accessed in more than one handler function.

HFONT hfontDlg;

//
// FUNCTION: CmdConnect(HWND, WORD, WORD, HWND)
//
// PURPOSE: Displays the "Connect" dialog box
//
// PARAMETERS:
// hwnd - Window handle
// wCommand - IDM_CONNECT (unused)
// wNotify - Notification number (unused)
// hwndCtrl - NULL (unused)
//
// RETURN VALUE:
//
// Always returns 0 - Message handled
//
// COMMENTS:
// To process the IDM_CONNECT message, call DialogBox() to display the
// Connect dialog box.

LRESULT CmdConnect(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
{
HMENU hmenu;

SetWindowText(hwnd, "IPX Chat Client"); // Change Window Title

// Start dialog box
if(DialogBox(hInst, "ConnectBox", hwnd, (DLGPROC)Connect))
{

// We have a connection! Set up message notification if
// data ready to be read or if connection is closed on us
if (WSAAsyncSelect(sock,
hwnd,
MW_DATAREADY,
FD_READ | FD_CLOSE) == SOCKET_ERROR)
{
MessageBox(hwnd, "WSAAsyncSelect Failed!", NULL, MB_OK);
CleanUp();
return 0;
}

// Connect has succeeded! Fix menus
hmenu = GetMenu(hwnd);
EnableMenuItem(hmenu, IDM_CONNECT, MF_GRAYED);
EnableMenuItem(hmenu, IDM_LISTEN, MF_GRAYED);
EnableMenuItem(hmenu, IDM_DISCONNECT, MF_ENABLED);
return 0;
}

// Connection failed - reset window title
SetWindowText(hwnd, szTitle);
return 0;
}


//
// FUNCTION: Connect(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for "Connect" dialog box.
//
// PARAMETERS:
// hdlg - window handle of the dialog box
// wMessage - type of message
// wparam - message-specific information
// lparam - message-specific information
//
// RETURN VALUE:
// TRUE - message handled
// FALSE - message not handled
//
// COMMENTS:
//
// Gets connection information from user and then establishes a connection.
//
// Connect when user clicks on the OK button. Kill Dialog when connection
// established.
//

LRESULT CALLBACK Connect(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam)
{
return DispMessage(&msdiConnect, hdlg, uMessage, wparam, lparam);
}


//
// FUNCTION: MsgConnectInit(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: To center dialog and limit size of edit controls
//
// PARAMETERS:
// hdlg - The window handing the message.
// uMessage - The message number. (unused).
// wparam - Message specific data (unused).
// lparam - Message specific data (unused).
//
// RETURN VALUE:
// Always returns 0 - message handled.
//
// COMMENTS:
// Set size of edit controls for the following
// Network 8 chars (4 2-digit hex numbers)
// Node 12 chars (6 2-digit hex numbers)
// Socket 4 chars (2 2-digit hex numbers)
//

LRESULT MsgConnectInit(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam)
{

// Create a font to use
hfontDlg = CreateFont(14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
VARIABLE_PITCH | FF_SWISS, "");

// Center the dialog over the application window
CenterWindow (hdlg, GetWindow (hdlg, GW_OWNER));

// Limit size of edit controls
SendDlgItemMessage(hdlg, CD_NETWORK, EM_LIMITTEXT, 8, 0);
SendDlgItemMessage(hdlg, CD_NODE, EM_LIMITTEXT, 12, 0);
SendDlgItemMessage(hdlg, CD_SOCKET, EM_LIMITTEXT, 4, 0);

// Initialize Edit Controls
SetDlgItemText(hdlg, CD_NETWORK, szConnectNetwork);
SetDlgItemText(hdlg, CD_NODE, szConnectNode);
SetDlgItemText(hdlg, CD_SOCKET, szConnectSocket);

return (TRUE);
}

//
// FUNCTION: MsgConnectCommand(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Process WM_COMMAND message sent to the Connect box.
//
// PARAMETERS:
// hwnd - The window handing the message.
// uMessage - The message number. (unused).
// wparam - Message specific data (unused).
// lparam - Message specific data (unused).
//
// RETURN VALUE:
// Always returns 0 - message handled.
//
// COMMENTS:
// Uses this DispCommand function defined in wndproc.c combined
// with the cmdiConnect structure defined in this file to handle
// the command messages for the Connect dialog box.
//

LRESULT MsgConnectCommand(HWND hwnd,
UINT uMessage,
WPARAM wparam,
LPARAM lparam)
{
return DispCommand(&cmdiConnect, hwnd, wparam, lparam);
}

//
// FUNCTION: CmdConnectDone(HWND, WORD, HWND)
//
// PURPOSE: Free the Connect box and related data.
//
// PARAMETERS:
// hdlg - The window handling the command.
// wCommand - The command to be handled (unused).
// wNotify - Notification number (unused)
// hwndCtrl - NULL (unused).
//
// RETURN VALUE:
// Always returns TRUE.
//
// COMMENTS:
// Cleans up sockets then calls EndDialog to finish the dialog session.
//

LRESULT CmdConnectDone(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl)
{

CleanUp(); // Free any aborted socket resources
EndDialog(hdlg, FALSE); // Exit Dialog -- rtrn false since no connection
return TRUE;
}

//
// FUNCTION: CmdConnectNow(HWND, WORD, HWND)
//
// PURPOSE: Establish the connection
//
// PARAMETERS:
// hdlg - The window handling the command.
// wCommand - The command to be handled (unused).
// wNotify - Notification number (unused)
// hwndCtrl - NULL (unused).
//
// RETURN VALUE:
// Always returns TRUE.
//
// COMMENTS:
// Makes Connection calls
//

LRESULT CmdConnectNow(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl)
{
char outtext[128];
WORD wVersionRequested;
WSADATA wsaData;


GetDlgItemText(hdlg, CD_NETWORK, szConnectNetwork, 9); // Get Network Number
AtoH(szConnectNetwork, (char *)&RemAddr.sa_netnum, 4); // Network order

GetDlgItemText(hdlg, CD_NODE, szConnectNode, 13); // Get Node Number
AtoH((char *)szConnectNode, (char *)&RemAddr.sa_nodenum, 6); // Network order

GetDlgItemText(hdlg, CD_SOCKET, szConnectSocket, 5); // Get Socket Number
AtoH((char *)szConnectSocket, (char *)&RemAddr.sa_socket, 2); // Network order

RemAddr.sa_family = AF_IPX; // IPX Family
wVersionRequested = MAKEWORD(1, 1);

SetDlgItemText(hdlg, CD_STATUS, "Calling WSAStartup");

// Initialize winsock dll
if(WSAStartup(wVersionRequested, &wsaData) == SOCKET_ERROR)
{
SetDlgItemText(hdlg, CD_STATUS, "WSAStartup failed");
return TRUE;
}

SetDlgItemText(hdlg, CD_STATUS, "WSAStartup Succeeded");

SetDlgItemText(hdlg, CD_STATUS, "Calling socket()");

// get socket handle
sock = socket(AF_IPX, // IPX family
SOCK_SEQPACKET, // Message mode data xfers
NSPROTO_SPX); // SPX = Connection Oriented

if(sock == INVALID_SOCKET) {
SetDlgItemText(hdlg, CD_STATUS, "ERROR on socket()");
WSACleanup();
return TRUE;
}

SetDlgItemText(hdlg, CD_STATUS, "socket() Succeeded");

SetDlgItemText(hdlg, CD_STATUS, "Calling connect()");

// Call specified address (we block here since I don't have anything better
// to do).
if(connect(sock, (struct sockaddr *)&RemAddr, sizeof(RemAddr)) == SOCKET_ERROR)
{
// Failed! Post status and cleanup
sprintf(outtext, "connect() failed, error %u", WSAGetLastError());
SetDlgItemText(hdlg, CD_STATUS, outtext);
closesocket(sock);
WSACleanup();
return TRUE;
}

// We've got a connection! Kill the dialog
SetDlgItemText(hdlg, CD_STATUS, "connect() succeeded!");

EndDialog(hdlg, TRUE); // Exit the dialog
DeleteObject (hfontDlg);
return (TRUE);
}