www.pudn.com > globchat.zip > MISC.C, change:1997-10-05,size:10892b


// 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 (C) 1993-1997  Microsoft Corporation.  All Rights Reserved. 
// 
//  MODULE:   misc.c 
// 
//  PURPOSE:  Contains all helper functions "global" to the application. 
// 
//  FUNCTIONS: 
//    CenterWindow    - Center one window over another. 
//    ReceiveInBox    - Reads incoming socket data. 
//    SendOutBox      - Writes outgoing socket data. 
//    AtoH            - Converts ascii string to network order hex 
//    BtoH            - Converts ascii byte to hex 
//    senddatamessage - Sends a message to the server 
//    recvdatamessage - Receives a message from the server 
// 
//  COMMENTS: 
// 
// 
 
#include <windows.h>            // required for all Windows applications 
#include <windowsx.h> 
#include <wsipx.h> 
#include <wsnetbs.h> 
#include <nspapi.h> 
#include "globals.h"            // prototypes specific to this application 
 
 
 
// 
//  FUNCTION: CenterWindow(HWND, HWND) 
// 
//  PURPOSE:  Center one window over another. 
// 
//  PARAMETERS: 
//    hwndChild - The handle of the window to be centered. 
//    hwndParent- The handle of the window to center on. 
// 
//  RETURN VALUE: 
// 
//    TRUE  - Success 
//    FALSE - Failure 
// 
//  COMMENTS: 
// 
//    Dialog boxes take on the screen position that they were designed 
//    at, which is not always appropriate. Centering the dialog over a 
//    particular window usually results in a better position. 
// 
 
BOOL CenterWindow(HWND hwndChild, HWND hwndParent) 
{ 
    RECT    rcChild, rcParent; 
    int     cxChild, cyChild, cxParent, cyParent; 
    int     cxScreen, cyScreen, xNew, yNew; 
    HDC     hdc; 
 
    // Get the Height and Width of the child window 
    GetWindowRect(hwndChild, &rcChild); 
    cxChild = rcChild.right - rcChild.left; 
    cyChild = rcChild.bottom - rcChild.top; 
 
    // Get the Height and Width of the parent window 
    GetWindowRect(hwndParent, &rcParent); 
    cxParent = rcParent.right - rcParent.left; 
    cyParent = rcParent.bottom - rcParent.top; 
 
    // Get the display limits 
    hdc = GetDC(hwndChild); 
    cxScreen = GetDeviceCaps(hdc, HORZRES); 
    cyScreen = GetDeviceCaps(hdc, VERTRES); 
    ReleaseDC(hwndChild, hdc); 
 
    // Calculate new X position, then adjust for screen 
    xNew = rcParent.left + ((cxParent - cxChild) / 2); 
    if (xNew < 0) 
    { 
        xNew = 0; 
    } 
    else if ((xNew + cxChild) > cxScreen) 
    { 
        xNew = cxScreen - cxChild; 
    } 
 
    // Calculate new Y position, then adjust for screen 
    yNew = rcParent.top  + ((cyParent - cyChild) / 2); 
    if (yNew < 0) 
    { 
        yNew = 0; 
    } 
    else if ((yNew + cyChild) > cyScreen) 
    { 
        yNew = cyScreen - cyChild; 
    } 
 
    // Set it, and return 
    return SetWindowPos(hwndChild, 
                        NULL, 
                        xNew, yNew, 
                        0, 0, 
                        SWP_NOSIZE | SWP_NOZORDER); 
} 
 
// 
//  FUNCTION: ReceiveInBox(HWND, WPARAM, LPARAM, char *, int) 
// 
//  PURPOSE:  Reads incoming data from socket and process message 
// 
//  PARAMETERS: 
//    hWnd      - Handle to current window 
//    uParam    - WPARAM (unused) 
//    lParam    - LPARAM contains event (FD_READ or FD_CLOSE). 
//    szRBuf    - Receive Buffer 
//    cRBufLen  - size of Receive Buffer 
// 
//  RETURN VALUE: 
// 
//    TRUE  - Data Read 
//    FALSE - If FD_CLOSE message or recv failed 
// 
//  COMMENTS: 
// 
//    Called if socket has data OR if it is closed.  If closed post 
//    WM_DISCONNECTED message.  Else read data and make sure it is 
//    NULL terminated. 
// 
 
BOOL ReceiveInBox(HWND hWnd, WPARAM uParam, LPARAM lParam, char * szRBuf, int cRBufLen) 
{ 
    char outtext[80]; 
 
 
    if (LOWORD(lParam) == FD_CLOSE)                   // Is this a FD_CLOSE event? 
    { 
        SendMessage(hWnd, MW_DISCONNECTED, 0, 0);     // Yes, post message 
        return(FALSE); 
    } 
 
    if (!recvdatamessage(&MySock, &xferbuf))         // Receive data 
    { 
        return(TRUE); 
    } 
 
    // Switch on message command 
    switch (xferbuf.hdr.command) 
    { 
        case XFER_DATA:   // Chat data...put it in buffer 
            lstrcpy(szRBuf, xferbuf.data); 
            cRBufLen = xferbuf.hdr.length - HDRSIZE; 
            break; 
 
        case SESSION_CLOSE:  // Peer killed us...cleanup 
            MySock.status = SOCKSTAT_AVAILABLE; 
 
            // Clear event indicator since we need to transfer message 
         // indications to the dialog we are about to create 
            if (WSAAsyncSelect(MySock.sock, hWnd, 0, 0) == SOCKET_ERROR) 
            { 
                // oops 
                return FALSE; 
            } 
            PostMessage(hWnd, WM_COMMAND, MAKELONG(IDM_SELECT, 0), 0); 
 
            wsprintf(outtext, GetStringRes(IDS_CHAT_AVAILABLE), MySock.name); 
            SetWindowText(hWnd, outtext); 
            return FALSE; 
 
        default: 
            break; 
            // unexpected meesage...drop it 
    } 
    return TRUE; 
} 
 
// 
//  FUNCTION: SendOutBox(char *, int) 
// 
//  PURPOSE:  Sends outbox text via data message 
// 
//  PARAMETERS: 
//    szSBuf    - Send Buffer 
//    cSBufLen  - size of Send Buffer 
// 
//  COMMENTS: 
// 
//    Writes send buffer to socket 
// 
 
void SendOutBox(char * szSBuf, int cSBufLen) 
{ 
    xferbuf.hdr.signature = MYSIGNATURE; 
    xferbuf.hdr.length = cSBufLen + HDRSIZE; 
    xferbuf.hdr.command = XFER_DATA; 
    lstrcpy(xferbuf.data, szSBuf); 
    senddatamessage(MySock.sock, &xferbuf); 
    return; 
} 
 
// 
//  FUNCTION: AtoH(char *, char *, int) 
// 
//  PURPOSE:  Converts ascii string to network order hex 
// 
//  PARAMETERS: 
//    src    - pointer to input ascii string 
//    dest   - pointer to output hex 
//    destlen - size of dest 
// 
//  COMMENTS: 
// 
//    2 ascii bytes make a hex byte so must put 1st ascii byte of pair 
//    into upper nibble and 2nd ascii byte of pair into lower nibble. 
// 
 
void AtoH(char * src, char * dest, int destlen) 
{ 
    char * srcptr; 
 
    srcptr = src; 
 
    while(destlen--) 
    { 
    *dest = BtoH(*srcptr++) << 4;    // Put 1st ascii byte in upper nibble. 
    *dest++ += BtoH(*srcptr++);      // Add 2nd ascii byte to above. 
    } 
} 
 
// 
//  FUNCTION: BtoH(char *, char *, int) 
// 
//  PURPOSE:  Converts ascii byte to numeric 
// 
//  PARAMETERS: 
//    ch - ascii byte to convert 
// 
//  RETURNS: 
//    associated numeric value 
// 
//  COMMENTS: 
// 
//    Will convert any hex ascii digit to its numeric counterpart. 
//    Puts in 0xff if not a valid hex digit. 
// 
 
unsigned char BtoH(char ch) 
{ 
    if (ch >= '0' && ch <= '9') return (ch - '0');        // Handle numerals 
    if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA);  // Handle capitol hex digits 
    if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 0xA);  // Handle small hex digits 
    return(255); 
} 
 
// 
//  FUNCTION: senddatamessage(SOCKET, LPDATAMSG) 
// 
//  PURPOSE:  sends a chat message to the server 
// 
//  PARAMETERS: 
//    sock    - our socket handle 
//    sendbuf - the message to send 
// 
//  RETURNS: 
//    ascii byte 
// 
//  COMMENTS: 
//    Send() may not be able to send entire message continue to send until 
//    entire message is sent 
// 
 
BOOL senddatamessage (SOCKET sock, LPDATAMSG sendbuf) 
{ 
    int totalbytes, bytessent; 
 
    bytessent = 0;                          // Set initial count to zero 
    totalbytes = sendbuf->hdr.length;     // Set total bytes to send 
 
   // loop until entire message is sent 
    while(bytessent < totalbytes) 
    { 
        bytessent += send(sock, 
                          (char *)sendbuf + bytessent, 
                          totalbytes - bytessent, 
                          0); 
    } 
 
    return TRUE; 
} 
 
// 
//  FUNCTION: recvdatamessage(LPSOCKDATA, LPDATAMSG) 
// 
//  PURPOSE:  receives chat message from server 
// 
//  PARAMETERS: 
//    lpSockdat - SOCKDATA structure 
//    recvbuf   - buffer for incoming data 
// 
//  RETURNS: 
//    TRUE  - Message received 
//    FALSE - Message not received 
// 
//  COMMENTS: 
//   For stream sockets we will need to make sure that we read 
//    an entire message--no more, no less.  Find message size from 
//    message header. 
// 
 
BOOL recvdatamessage (LPSOCKDATA lpSockdat, LPDATAMSG recvbuf) 
{ 
    int readsize, totalbytesread, msgsize, bytesread; 
 
    if (lpSockdat->type == SOCK_SEQPACKET) 
    { 
        // Message mode protocol!!  Just post one big read. 
        readsize = sizeof(*recvbuf); 
    } 
    else 
    { 
        // Stream mode protocol!!  Just read header...then read data (data size determined 
        // from header) 
        readsize = HDRSIZE; 
    } 
    if((totalbytesread = recv(lpSockdat->sock, (char *)recvbuf, readsize, 0)) == SOCKET_ERROR) 
    { 
        // ERROR  -- just return 
        return FALSE; 
    } 
 
    // Check for my signature at the beginning of the message 
    if(recvbuf->hdr.signature != MYSIGNATURE) 
    { 
        // I've received some data that's in mid message--drop it 
        return FALSE; 
    } 
 
    // Read size of message 
    msgsize = recvbuf->hdr.length; 
    readsize = msgsize - totalbytesread; 
 
    while(totalbytesread < msgsize) 
    { 
        // we should only get hear for stream sockets 
        if((bytesread = recv(lpSockdat->sock, 
                             (char *)recvbuf + totalbytesread, 
                             readsize, 
                             0)) == SOCKET_ERROR) 
        { 
            if (WSAGetLastError() != WSAEWOULDBLOCK) 
            { 
                // ERROR -- throw out message 
                return FALSE; 
            } 
            // If you got a WSAWOULDBLOCK error, just keep trying...it shouldn't take 
            // too much longer for the rest of the message to get here.  Let's hope 
            // we don't hog the CPU so the data doesn't get to us. 
        } 
        totalbytesread += bytesread; 
        readsize -= bytesread; 
    } 
 
    return TRUE; 
} 
 
//--------------------------------------------------------------------------- 
// 
// FUNCTION:    GetStringRes (int id INPUT ONLY) 
// 
// COMMENTS:    Load the resource string with the ID given, and return a 
//              pointer to it.  Notice that the buffer is common memory so 
//              the string must be used before this call is made a second time. 
// 
//--------------------------------------------------------------------------- 
 
LPTSTR GetStringRes (int id) 
{ 
  static TCHAR buffer[MAX_PATH]; 
 
  buffer[0]=0; 
  LoadString (GetModuleHandle (NULL), id, buffer, MAX_PATH); 
  return buffer; 
}