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

📄 dt3.cpp

📁 USB终端的设置代码
💻 CPP
字号:
// DT3.cpp : Defines the entry point for the application.
// This program is a "minimum feature" USB Dumb Terminal program
// It's goal is to show how a simple serial device can be simply connected to USB using
// a USB I/O device.  This example uses the EZ-USB microcontroller and the firmware to
// implement the USB-to-serial-to-USB conversion is also available as an example program.
//
// See the accompanying documentation for a description of this example program
//
// Please send any corrections or enhancements to john@USB-By-Example.com

#include "stdafx.h"
#include "resource.h"

extern "C" {
// Declare the C libraries used
#include "setupapi.h"
#include "hidsdi.h"
#include "process.h"
}

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;						// current instance
HWND MainWindow;						// Handle for main window
TCHAR szTitle[MAX_LOADSTRING];			// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];
char Buffer[2000];						// A screen full of characters
int BufferIndex;						// A pointer into Buffer
const char *SignOn  = "\n Select Connect from the File menu to search for 'Serial1' USB I/O device -";
const char *Found   = "-> found\n";
const char *Special = " ** F1 Pressed ** ";
HANDLE ReadHandle, WriteHandle;
bool FullDuplex;

// Forward declarations of functions included in this program
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM);
BOOL				OpenUSBdevice(char*);
DWORD WINAPI		ListenToUSB(LPVOID);
DWORD				DisplayError(const char*);

// Entry point for this program
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
// Declare local variables
	MSG msg;
	HACCEL hAccelTable;

// Initialize global variables
	FullDuplex = true; ReadHandle = 0; WriteHandle = 0;
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_DT3, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

// Initialize application
	if (!InitInstance (hInstance, nCmdShow)) { return FALSE; }
	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_DT3);

// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0)) {
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	return msg.wParam;
}

//  Register the window class.  (required)
ATOM MyRegisterClass(HINSTANCE hInstance) {
	WNDCLASSEX wcex;

	wcex.cbSize			= sizeof(WNDCLASSEX); 
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, (LPCTSTR)IDI_DT3);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= (LPCSTR)IDC_DT3;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

	return RegisterClassEx(&wcex);
}

// Initialize the program and create main window
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) {
	HWND hWnd;

	hInst = hInstance; // Store instance handle in our global variable
	hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
	if (!hWnd) { return FALSE; }

	MainWindow = hWnd;
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	return TRUE;
}

//  Processe messages for the main window.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
	int ID, Event, Success, i;
	PAINTSTRUCT ps;
	HDC hdc;
	RECT rt;
	HANDLE ThreadHandle;
	HMENU hMainMenu, hSubMenu;
	char WriteBuffer[2];
	DWORD BytesWritten, ThreadID;
	
	switch (message) {
		case WM_COMMAND:
			ID = LOWORD(wParam); Event = HIWORD(wParam); 
// Parse the menu selections:
			switch (ID) {
				case IDM_ABOUT: DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); return 0;
				case IDM_EXIT: DestroyWindow(hWnd); return 0;
				case IDM_FULLDUPLEX:	
// Toggle the Full/Half Duplex flag
					hMainMenu = GetMenu(hWnd); hSubMenu = GetSubMenu(hMainMenu, 0);
					if (FullDuplex = !FullDuplex) { CheckMenuItem(hSubMenu, IDM_FULLDUPLEX, MF_BYCOMMAND | MF_CHECKED); }
					else { CheckMenuItem(hSubMenu, IDM_FULLDUPLEX, MF_BYCOMMAND | MF_UNCHECKED);}
					return 0;
				case IDM_CONNECT:
// Look for the Serial1 USB device
					if (!OpenUSBdevice("Serial1")) { DisplayError("Could not find 'Serial1' device"); }
					else {
						for (i = 0; i<(int)strlen(Found); i++) { Buffer[BufferIndex++] = Found[i]; }
						InvalidateRect(MainWindow, NULL, 1);
// Serial USB device is open, create a thread to listen for characters
						ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ListenToUSB, NULL, 0, &ThreadID);
						if ((int)ThreadHandle == 0) { DisplayError("Could not start USB Listener Thread"); }
// Send an initial character to let the USB I/O device know we are ready
						WriteBuffer[0] = 0; WriteBuffer[1] = 0;
						Success = WriteFile(WriteHandle, WriteBuffer, 2, &BytesWritten, NULL);
						if (Success == 0) { DisplayError("Could not write to the 'Serial1' device"); }
					}
					return 0;
				}
			break;	// and send unprocessed menu message to Windows
		case WM_PAINT:
// This is a minimal repaint.  
// A "real" terminal program would process characters such as BS, TAB, CR, LF 
			hdc = BeginPaint(hWnd, &ps); 
			GetClientRect(hWnd, &rt);
			DrawText(hdc, Buffer, BufferIndex, &rt, 0);
			EndPaint(hWnd, &ps); 
			return 0;
		case WM_DESTROY: PostQuitMessage(0); return 0;
		case WM_CHAR:
// Send the character to the USB I/O device
			WriteBuffer[0] = 0;	// Report ID
			WriteBuffer[1] = (char)wParam;
			Success = WriteFile(WriteHandle, WriteBuffer, 2, &BytesWritten, NULL);
// Create a local echo if required
			if (!FullDuplex) { Buffer[BufferIndex++] = (char)wParam; InvalidateRect(hWnd, NULL, 1); }
			return 0;
		case WM_KEYDOWN:
// Note that WM_CHAR does not process the Function keys
			WriteBuffer[0] = 0;
			if ((char)wParam == 112) { // F1 Function Key, send a string
				for (i=0; i<(int)strlen(Special); i++) {
					WriteBuffer[1] = Special[i];
					Success = WriteFile(WriteHandle, WriteBuffer, 2, &BytesWritten, NULL);
				}
				
			}
			if ((char)wParam == 113) { // F2 Function key, request a string
				WriteBuffer[1] = (char)wParam;
				Success = WriteFile(WriteHandle, WriteBuffer, 2, &BytesWritten, NULL);
			}
			return 0;
		case WM_CREATE:
// Say Hello to the User
			for (BufferIndex = 0; BufferIndex<(int)strlen(SignOn); BufferIndex++) { Buffer[BufferIndex] = SignOn[BufferIndex]; }
			InvalidateRect(hWnd, NULL, 1);
			return 0;
		}
// Pass unprocessed messages back to Windows
	return DefWindowProc(hWnd, message, wParam, lParam);
}

// Mesage handler for About box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
	int ID = LOWORD(wParam); 
	switch (message) {
		case WM_INITDIALOG: return TRUE;
		case WM_COMMAND: if (ID == IDOK || ID == IDCANCEL) { EndDialog(hDlg, ID); return TRUE; }
			break;
		}
    return FALSE;
}


// Support routines
BOOL OpenUSBdevice(char DeviceName[]) {
// Search through the attached HID devices for "DeviceName"
	
// Declare the local data structures used
	struct _GUID HidGuid;
	SP_INTERFACE_DEVICE_DATA DeviceInterfaceData;
	struct {DWORD cbSize; char DevicePath[256];} FunctionClassDeviceData;
	int Success, HidDevice, i;
	HANDLE PnPHandle, HidHandle;
	unsigned long BytesReturned;
	char buffer[256];
	BOOL Openned;

// First, get my class identifier
	HidD_GetHidGuid(&HidGuid);

// Get a handle for the Plug and Play node and request currently active HID devices
	PnPHandle = SetupDiGetClassDevs(&HidGuid,0,0,0x12);
	if (int(PnPHandle) == -1) {	DisplayError("Could not attach to PnP node"); return FALSE; }

	Openned = false;
// Lets look for a maximum of 20 HID devices
	for (HidDevice = 0; (HidDevice < 20) && !Openned; HidDevice++) {
// Give the user some feedback
	Buffer[BufferIndex++] = 45;  // "-"
	InvalidateRect(MainWindow, NULL, 1);

// Initialize our Data
		DeviceInterfaceData.cbSize = 28; // Length of data structure in bytes

// Is there a HID device at this table entry
		Success = SetupDiEnumDeviceInterfaces(PnPHandle, 0, &HidGuid, HidDevice, &DeviceInterfaceData);
		if (Success == 1) {
// There is a device here, get it's name
			FunctionClassDeviceData.cbSize = 5;
			Success = SetupDiGetDeviceInterfaceDetail(PnPHandle, &DeviceInterfaceData, 
				PSP_INTERFACE_DEVICE_DETAIL_DATA(&FunctionClassDeviceData), 256, &BytesReturned, 0);
			if (Success == 0) {	DisplayError("Could not find the system name for this HID device"); return FALSE; }
// Can now open this HID device
			HidHandle = CreateFile(FunctionClassDeviceData.DevicePath, 0xC0000000, 3, NULL, 3, 0, NULL);
			if ((int)HidHandle == -1) { DisplayError("Could not open HID device"); return FALSE; }
// Is it OUR HID device?
			if (HidD_GetProductString(HidHandle, buffer, sizeof(buffer))) {
// Compare incoming string with UNICODE string
				Openned = true; i = 0;
				while (DeviceName[i] != 0) { if (buffer[2*i] != DeviceName[i]) {Openned = false;} i++;}
				if (Openned) {
// We have found our device. Open two handles to it (one for each thread)
					ReadHandle = CreateFile(FunctionClassDeviceData.DevicePath, 0xC0000000, 3, NULL, 3, 0, NULL);
					WriteHandle = CreateFile(FunctionClassDeviceData.DevicePath, 0xC0000000, 3, NULL, 3, 0, NULL);
				}
			}
			CloseHandle(HidHandle);
		} // if (SetupDiEnumDeviceInterfaces . .
	} // for (HidDevice = 0; (HidDevice < 20) && !Openned; HidDevice++)
	CloseHandle(PnPHandle);
	return Openned;
}

//	Declare the thread that will wait for characters from the USB device
DWORD WINAPI ListenToUSB(LPVOID Param) {
// Collect characters from the USB device and send them to the display
	char ReadBuffer[2];
	int Success;
	unsigned long BytesReturned;

	while (1) {	
		Success = ReadFile(ReadHandle, ReadBuffer, 2, &BytesReturned, NULL);
		if (ReadBuffer[1] != 0) { Buffer[BufferIndex++] = ReadBuffer[1]; InvalidateRect(MainWindow, NULL, 1); }
	};
	return 0;
}	

//	Display various error messages
DWORD DisplayError (const char ErrorText[]) {
	int i = MessageBox(MainWindow, ErrorText, "Error", MB_ICONSTOP);
	return 0;
}

⌨️ 快捷键说明

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