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

📄 sendit.cpp

📁 《Windows CE 权威指南》(作者:(美)CHRIS MUENCH
💻 CPP
字号:
// SendIt.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "SendIt.h"
#include <commctrl.h>

// <BOOK_ADDON Chapter 9.5.1> **************************************
#include <winsock.h>
#define DESIRED_WINSOCK_VERSION   0x0101  // we like winsock ver 1.1...
#define MINIMUM_WINSOCK_VERSION   0x0001  // ...but we'll take ver 1.0
#define MAX_BUF_LEN				  1000    // max telegram size
#define PACKET_TYPE_FILE          0x46494c45L     // "FILE"
#define PACKET_TYPE_NACK          0x4e41434bL     // "NACK"
#define MPPort					  4321	// Using Port 4321
#define WM_SOCKET_SELECT          (WM_USER + 100)	// WSOCK Packet
// received
typedef INT						   SOCKERR;        // A socket error code.
typedef struct _PACKET_FILE	// Our Telegram Structure
{
    DWORD       type;                   // Must be PACKET_TYPE_FILE.
    DWORD       cbFile;                 // Use data size
    DWORD	    PakSize;		    // Packet size
    DWORD	    Code;			    // Windows Message for receiver
    CHAR        szFile[MAX_BUF_LEN];    // The use data
} PACKET_FILE, FAR * LPPACKET_FILE;

SOCKET          sCommand = INVALID_SOCKET; // Command socket.
CRITICAL_SECTION m_csec;			 // Critical Section handle
BOOL		    MPServerRunning=FALSE;	 // is TRUE if thread runs

SOCKERR ResetSocket( SOCKET sock )
{
    LINGER linger;
    if( sock == INVALID_SOCKET )
        return 0;
    linger.l_onoff  = TRUE;
    linger.l_linger = 0;
    setsockopt( sock,
                SOL_SOCKET,
                SO_LINGER,
                (CHAR FAR *)&linger,
                sizeof(linger) );
    return closesocket( sock );
}   // ResetSocket

SOCKERR CreateSocket( SOCKET FAR * psock,
                      INT          type,
                      ULONG        address,
                      WORD         port )
{
    SOCKET  sNew;
    SOCKERR serr;
    sNew = socket( PF_INET, type, 0 );
    serr = ( sNew == INVALID_SOCKET ) ? WSAGetLastError() : 0;
    if( serr == 0 )
    {
        SOCKADDR_IN sockAddr;
        sockAddr.sin_family      = AF_INET;
        sockAddr.sin_addr.s_addr = address;
        sockAddr.sin_port        = port;
        if( bind( sNew, (SOCKADDR FAR *)&sockAddr, 
				  sizeof(sockAddr) ) != 0 )
        {
            serr = WSAGetLastError();
        }
    }
    if( serr != 0 )
    {
        ResetSocket( sNew );
        sNew = INVALID_SOCKET;
    }
    *psock = sNew;
    return serr;
}   // CreateSocket

DWORD WINAPI	SCeThread( LPVOID pParam )
{
INT			cbRead;		// Bytes read
PACKET_FILE		filePacket;		// buffer for a datagramm
SOCKADDR_IN		addrClient;		// The address of the sender
INT			cbAddrClient;	// Size of the addrClient buffer
BYTE		     *tBuffer=NULL;	// a temporary buffer for the use
// data
int			endless;		// a loop flag

	cbAddrClient = sizeof(addrClient);
	endless=TRUE;
	while (endless==TRUE)
	{
		cbRead = recvfrom(sCommand,
				(CHAR FAR *)&filePacket,sizeof(filePacket),
				0,(SOCKADDR FAR *)&addrClient,&cbAddrClient );
		// This command blocks until something comes into the
// WinSock Buffer
		if (cbRead<1) 	// Socket was reset cvRead is zero
		{			// we use this to end the thread
			endless=FALSE;
			if (cbRead==SOCKET_ERROR)
			{
				cbRead=WSAGetLastError();
				if (cbRead==WSAEWOULDBLOCK)
				{
					endless=TRUE;
					continue;
				}
			}
		}
		EnterCriticalSection(&m_csec);	
// We do not want other thread interrupting us while
// reading the WINSOCK buffer
		switch (filePacket.type)
		{
		   case PACKET_TYPE_FILE:  // A well know telegram arrived
			if (filePacket.cbFile>0)
			{
				tBuffer = (BYTE *)LocalAlloc(LMEM_ZEROINIT, 
									filePacket.cbFile);
				memcpy(tBuffer,filePacket.szFile,
						filePacket.cbFile);
			}
			PostMessage((HWND)pParam, filePacket.Code,
						(WPARAM)tBuffer,
						(LPARAM)addrClient.sin_addr.s_addr);
		     break;
		  case PACKET_TYPE_NACK:
			endless=FALSE;
		     break;
  		  default:
			// Ignore Packet
		     break;
		}
		LeaveCriticalSection(&m_csec);
	}
	return TRUE;
}

BOOL InitServer(HWND hwnd)
{
WSADATA           wsadata;
SOCKERR           serr;
DWORD ThreadId = 0L; 
HANDLE	    	m_pCeThread;			 // thread handle

	if (MPServerRunning)	return TRUE;

	serr = WSAStartup( DESIRED_WINSOCK_VERSION, &wsadata );
	if( serr != 0 )	return FALSE;	// More error handling here
	if( wsadata.wVersion < MINIMUM_WINSOCK_VERSION ) return FALSE;
	serr = CreateSocket( &sCommand, SOCK_DGRAM,
		               htonl( INADDR_ANY ), htons(MPPort));
	if( serr != 0 )  return FALSE; 	// More error handling here

	m_pCeThread = CreateThread( NULL, 0, SCeThread, hwnd,0L,&ThreadId);	
//Pass hWnd to Thread
	CloseHandle(m_pCeThread);
	InitializeCriticalSection(&m_csec);
	MPServerRunning=TRUE;

	return TRUE;
}

BOOL CloseServer(void)
{
	if (MPServerRunning)
	{
		ResetSocket(sCommand);
		WSACleanup();
		MPServerRunning=FALSE;
	}
	return TRUE;
}

SOCKERR SendWSockPacket( SOCKET sock, int	len, BYTE *Buffer,
				 DWORD code, TCHAR *tIP)
{
PACKET_FILE filePacket;
INT         cbWritten;
SOCKADDR_IN saUdpServ;
char		mpip[20]; // yep, the IP Address has to be ANSI !!
int	i;

	if (tIP==NULL) return 0;
	for (i=0;i<(int)lstrlen(tIP);i++) mpip[i]=(char)tIP[i];
	mpip[i]=0;	// Converting the tIP Parameter to ANSI
	saUdpServ.sin_family = AF_INET;	// This is Important !!
			// It tells we are using the WINSOCK TCP/IP Layer
	saUdpServ.sin_addr.s_addr = inet_addr(mpip);
    saUdpServ.sin_port = htons(MPPort);	// supplying the Port Number

	// Preparing our telegram structure
	memset(filePacket.szFile,0,sizeof(filePacket.szFile));
    filePacket.type   = PACKET_TYPE_FILE;	// Packet Type
    filePacket.cbFile = len;
	filePacket.PakSize= len+(4*sizeof(DWORD));
	filePacket.Code	  = code;
    memcpy( filePacket.szFile, Buffer, len);

    cbWritten = sendto( sock,
				  (CHAR FAR *)&filePacket,
				  filePacket.PakSize,  0,
				  (SOCKADDR *) &saUdpServ,
				  sizeof ( SOCKADDR_IN ));
    return ( cbWritten == SOCKET_ERROR )
            ? WSAGetLastError() : 0;
}   // SendWSockPacket

BOOL SendPacket(WCHAR *Buffer, DWORD code,TCHAR *tIP)
{
BOOL ret;
long len;

	len=(wcslen(Buffer)+1)*sizeof(WCHAR); 
// Buffer = String incl. Terminating zero
	ret=SendWSockPacket( sCommand, len, (BYTE *)Buffer,code, tIP); 
    if( ret != 0 ) return FALSE;	// more error handling goes here
    return TRUE;
}
// </BOOK_ADDON Chapter 9.5.1> **************************************

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE			hInst;			// The current instance
HWND				hwndCB;			// The command bar handle

// Foward declarations of functions included in this code module:
ATOM				MyRegisterClass	(HINSTANCE hInstance, LPTSTR szWindowClass);
BOOL				InitInstance	(HINSTANCE, int);
LRESULT CALLBACK	WndProc			(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK	About			(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(	HINSTANCE hInstance,
					HINSTANCE hPrevInstance,
					LPTSTR    lpCmdLine,
					int       nCmdShow)
{
	MSG msg;
	HACCEL hAccelTable;

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SENDIT);

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0)) 
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
// <BOOK_ADDON Chapter 9.5.1> **************************************
	CloseServer();
// </BOOK_ADDON Chapter 9.5.1> **************************************
	return msg.wParam;
}

//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage is only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
	WNDCLASS	wc;

    wc.style			= CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc		= (WNDPROC) WndProc;
    wc.cbClsExtra		= 0;
    wc.cbWndExtra		= 0;
    wc.hInstance		= hInstance;
    wc.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SENDIT));
    wc.hCursor			= 0;
    wc.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName		= 0;
    wc.lpszClassName	= szWindowClass;

	return RegisterClass(&wc);
}

//
//  FUNCTION: InitInstance(HANDLE, int)
//
//  PURPOSE: Saves instance handle and creates main window
//
//  COMMENTS:
//
//    In this function, we save the instance handle in a global variable and
//    create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	HWND	hWnd;
	TCHAR	szTitle[MAX_LOADSTRING];			// The title bar text
	TCHAR	szWindowClass[MAX_LOADSTRING];		// The window class name

	hInst = hInstance;		// Store instance handle in our global variable
	// Initialize global strings
	LoadString(hInstance, IDC_SENDIT, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance, szWindowClass);

	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
#ifdef UNDER_CE // <BOOK_ADDON Chapter 9.5.1/> ****
	hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, 
		NULL, 
		hInstance, NULL);
// <BOOK_ADDON Chapter 9.5.1> *****************************
	#else
	hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
		0, 0, CW_USEDEFAULT, CW_USEDEFAULT, NULL, 
		LoadMenu(hInstance,MAKEINTRESOURCE(IDM_MENU)),
		hInstance, NULL);
#endif
// <BOOK_ADDON Chapter 9.5.1> *****************************
	if (!hWnd)
	{	
		return FALSE;
	}

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
#ifdef UDNER_CE // <BOOK_ADDON Chapter 9.5.1/> ****
	if (hwndCB)
		CommandBar_Show(hwndCB, TRUE);
#endif // <BOOK_ADDON Chapter 9.5.1/> ****

// <BOOK_ADDON Chapter 9.5.1> **************************************
	InitServer(hWnd);
// </BOOK_ADDON Chapter 9.5.1> **************************************
	return TRUE;
}

//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC hdc;
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	TCHAR szHello[MAX_LOADSTRING];

	switch (message) 
	{
		case WM_COMMAND:
			wmId    = LOWORD(wParam); 
			wmEvent = HIWORD(wParam); 
			// Parse the menu selections:
			switch (wmId)
			{
				case IDM_HELP_ABOUT:
				   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
				   break;
				case IDM_FILE_EXIT:
				   DestroyWindow(hWnd);
				   break;
// <BOOK_ADDON Chapter 9.5.1> **************************************
				case ID_SENDPACKET:
#ifdef UNDER_CE
					SendPacket(L"This was sent from Windows CE",
						     WM_SOCKET_SELECT,TEXT("192.168.55.1"));
#else
					SendPacket(L"This was sent from Windows NT/98",
				  		     WM_SOCKET_SELECT,TEXT("192.168.55.5"));
#endif
				   break;
// </BOOK_ADDON Chapter 9.5.1> **************************************
				default:
				   return DefWindowProc(hWnd, message, wParam, lParam);
			}
			break;
		case WM_CREATE:
#ifdef UNDER_CE // <BOOK_ADDON Chapter 9.5.1/> ****
			hwndCB = CommandBar_Create(hInst, hWnd, 1);			
			CommandBar_InsertMenubar(hwndCB, hInst, IDM_MENU, 0);
			CommandBar_AddAdornments(hwndCB, 0, 0);
#endif // <BOOK_ADDON Chapter 9.5.1/> ****
			break;
// <BOOK_ADDON Chapter 9.5.1> **************************************
		case WM_SOCKET_SELECT:
				TCHAR wsu[100];
				if (sizeof(TCHAR)==sizeof(WCHAR))
					wsprintf(wsu,TEXT("%s"),(TCHAR *)wParam);
				else
				{
					WCHAR *tTxt=(WCHAR *)wParam;
					for (int i=0;i<(int)wcslen(tTxt);i++)
						wsu[i]=(TCHAR)tTxt[i];
					wsu[i]=0;
				}	// Some Unicode to ANSI conversion

⌨️ 快捷键说明

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