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

📄 messenger.cpp

📁 局域网聊天工具。VC开发的一个局域网聊天工具。程序有详细注释。供网络编程的人参考和学习
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	// Ensure that the common control DLL is loaded. 
	icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
	icex.dwICC  = ICC_LISTVIEW_CLASSES;
	InitCommonControlsEx(&icex); 
 
	// Create the list-view window in report view with label 
	// editing enabled.
	GetClientRect (hwndParent, &rcl); 
	hWndListView = CreateWindow (WC_LISTVIEW, "", 
			WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_EDITLABELS | LVS_SINGLESEL | LVS_EX_TWOCLICKACTIVATE, 
			0, 0, rcl.right - rcl.left, rcl.bottom - rcl.top, 
			hwndParent, NULL, hInst, NULL); 
	return hWndListView;
}

///////////////////////////////////////////////////////////////////////////////////

void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {
	
	switch(id) {
	case ID_DELETE_FRIEND: {
		int i = ListView_GetNextItem(hWndList, -1, LVNI_ALL | LVNI_SELECTED);
		if(i != 0) 
			ListView_DeleteItem(hWndList, i);		
		break; }
	case ID_ADD_FRIEND: {
		// pop up the add friend dialog
		DialogBox(hInst, MAKEINTRESOURCE(IDD_ADD_FRIEND), hwnd, AddFriendDlgProc);
		// insert the new friend to the list view 
		int nCount = ListView_GetItemCount(hWndList);
		if(strcmp(szNewIP, "") != 0) {
			LVITEM li;
			li.mask = LVIF_STATE | LVIF_IMAGE; 
			li.state = 0; 
			li.stateMask = 0; 
			li.iSubItem = 0;
			li.iItem = nCount;
			li.iImage = 1;
			ListView_InsertItem(hWndList, &li);
			ListView_SetItemText(hWndList, nCount, 0, szNewIP);
			ListView_SetItemText(hWndList, nCount, 1, "Off");
			ListView_SetItemText(hWndList, nCount, 2, szNewIP);
		}
		break;}
	case ID_CLOSE:
		SendMessage(hwnd, WM_CLOSE, 0, 0);
		break;
	case ID_EXIT:
		SaveFriendList();
		// send an offline msg to all friends
		TCHAR sz[20];
		strcpy(sz, "offline msg");
		SendToAllFriends(sz, sizeof(sz));

		DestroyWindow(hwnd);
		break;
	case ID_ABOUT:
		MessageBox(NULL, "Help not implemented", "Messenger", MB_ICONINFORMATION);
	//	DialogBox(NULL, MAKEINTRESOURCE(IDD_DIALOG), hwnd, NULL);
		
		break;
	}
}

//////////////////////////////////////////////////////////////////////////////////

void SendToAllFriends(TCHAR* szBuf, int len) {

	TCHAR szIP[20];
	SOCKADDR_IN sa;
	int ret;
	int nCount = ListView_GetItemCount(hWndList);
	for(int i = 1; i < nCount; i++) {
		ListView_GetItemText(hWndList, i, 2, szIP, sizeof(szIP));
		sa.sin_family = AF_INET;
		sa.sin_port = htons(Port);
		sa.sin_addr.s_addr = inet_addr(szIP);
		ret = sendto(s, szBuf, len, 0, (SOCKADDR*) &sa, sizeof(sa));
		if(ret == SOCKET_ERROR) {
			MessageBox(NULL, "SendToAllFriends error!", "Messenger", 0);
		}
	}
}

/////////////////////////////////////////////////////////////////////////////////////

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	
 	switch(uMsg) {

	case WM_NOTIFY: {
		// process double click on the item of the list
		NMHDR* pnmhdr = (LPNMHDR)lParam;
		if((pnmhdr->hwndFrom == hWndList) && (pnmhdr->code == LVN_ITEMACTIVATE)) {
			int i = ListView_GetNextItem(hWndList, -1, LVNI_ALL | LVNI_SELECTED);
			if(i != 0) {
				TCHAR sz[20];
				ListView_GetItemText(hWndList, i, 0, sz, sizeof(sz));

				// pop up conversation dialog
				FRIEND frnd;
				ListView_GetItemText(hWndList, i, 0, frnd.szName, sizeof(frnd.szName));
				ListView_GetItemText(hWndList, i, 2, frnd.szIPAddress, sizeof(frnd.szIPAddress));
				// send a beginconversation msg 
				SOCKADDR_IN sa;
				TCHAR szBuf[1024];
				int ret;
				sa.sin_family = AF_INET;
				sa.sin_port = htons(Port);
				sa.sin_addr.s_addr = inet_addr(frnd.szIPAddress);
				strcpy(szBuf, "beginconversation msg");
				ret = sendto(s, szBuf, sizeof(szBuf), 0, (SOCKADDR*)&sa, sizeof(sa));
				if(ret == SOCKET_ERROR) {
					MessageBox(NULL, "sendto failed!", "Messenger", 0);
				}
				DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CONVERSATION), NULL, ConversationDlgProc, (LPARAM) &frnd);
			}
		}
		// rename the label
		LV_DISPINFO * pnmlvdi = (LV_DISPINFO*)lParam;
		if((pnmlvdi->hdr.hwndFrom == hWndList) && (pnmlvdi->hdr.code == LVN_ENDLABELEDIT)) {
			ListView_SetItemText(hWndList, pnmlvdi->item.iItem, 0, pnmlvdi->item.pszText);			
		}

		return 0; }
	case WM_CLOSE:
		ShowWindow(hwnd, SW_HIDE);
		return 0;
	case WM_TRAYICON: { // make tray icon
		if(wParam != MAINTRAYICON)
			return 0L;
		// load menu
		HMENU hTrayMenu;
		if((hTrayMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDM_TRAYMENU))) == NULL)
			return 0;
		HMENU hSubMenu = GetSubMenu(hTrayMenu, 0);
		if (hSubMenu == NULL)
			return 0;
		if (lParam == WM_RBUTTONUP)
		{
			SetMenuDefaultItem(hSubMenu, 0, TRUE);
			POINT pos;
			GetCursorPos(&pos);
			SetForegroundWindow(hwnd);
			TrackPopupMenu(hSubMenu, TPM_RIGHTALIGN|TPM_LEFTBUTTON
			|TPM_RIGHTBUTTON, pos.x, pos.y, 0, hwnd, NULL);
		}
		else if(lParam == WM_LBUTTONDOWN)
		{
			ShowWindow(hwnd, SW_RESTORE);
			SetForegroundWindow(hwnd);
		}
		return 1L; }
	case WM_COMMAND:
		OnCommand(hwnd, wParam, (HWND)lParam, NULL);
		return 0;

	case WM_CREATE: {
		hWnd = hwnd;
		// set the window to the appropriate style
		SetWindowPos(hwnd, HWND_TOP, 0, 0, 300, 600, SWP_NOMOVE | SWP_SHOWWINDOW);
		LONG l = GetWindowLong(hwnd, GWL_STYLE);
		l &= ~WS_MAXIMIZEBOX;
		SetWindowLong(hwnd, GWL_STYLE, l);

		// make tray icon
		NOTIFYICONDATA nid;
		nid.cbSize = sizeof(NOTIFYICONDATA);
		nid.hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, 0);
		nid.hWnd = hwnd;
		nid.uID = MAINTRAYICON;
		nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
		nid.uCallbackMessage = WM_TRAYICON;
		strcpy(nid.szTip, "Messenger");
		::Shell_NotifyIcon(NIM_ADD,&nid);
		
		// create the list view control
		hWndList = CreateListView(hwnd);

		// add header to the list view control
		LVCOLUMN lvc;
		lvc.mask = LVCF_WIDTH | LVCF_TEXT; 
 		lvc.cx = 150;
		lvc.pszText = "friends";
		ListView_InsertColumn(hWndList, 0, &lvc);
		lvc.pszText = "on / off";
		ListView_InsertColumn(hWndList, 1, &lvc);
		lvc.pszText = "IP Address";
		ListView_InsertColumn(hWndList, 2, &lvc);

		// create the image list
		HIMAGELIST hSmall; 
		HICON hIconItem; 
		hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), 
			GetSystemMetrics(SM_CYSMICON), ILC_COLOR, 1, 1); 		
		hIconItem = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ONLINE));
		ImageList_AddIcon(hSmall, hIconItem);
		hIconItem = LoadIcon(hInst, MAKEINTRESOURCE(IDI_OFFLINE));
		ImageList_AddIcon(hSmall, hIconItem);
		hIconItem = LoadIcon(hInst, MAKEINTRESOURCE(IDI_AWAY));
		ImageList_AddIcon(hSmall, hIconItem);
		ListView_SetImageList(hWndList, hSmall, LVSIL_SMALL); 

		// add all my friends and myself to the list view from the data file
		LVITEM li;
		li.mask = LVIF_STATE | LVIF_IMAGE; 
		li.state = 0; 
		li.stateMask = 0; 
		li.iSubItem = 0;
		li.iItem = 0;
		li.iImage = 0;
		ListView_InsertItem(hWndList, &li);
		ListView_SetItemText(hWndList, 0, 0, "我");
		ListView_SetItemText(hWndList, 0, 1, "On");
		
		LoadFriendList();

		// start up the winsock
		WSADATA wsaData;
		if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
			MessageBox(NULL, "failed to startup!", "Messenger", 0);
			return 0;
		}

		// create the socket, and bind it
		s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
		if(s == INVALID_SOCKET) {
			MessageBox(NULL, "failed to create the socket!", "Messenger", 0);
			return 0;
		}
		SOCKADDR_IN addr;
		addr.sin_family = AF_INET;
		addr.sin_port = htons(Port);    
		addr.sin_addr.s_addr = htonl(INADDR_ANY);
		if(bind(s, (SOCKADDR*) &addr, sizeof(addr)) == SOCKET_ERROR) {
			MessageBox(NULL, "failed to bind the socket!", "Messenger", 0);
			closesocket(s);;
			return 0;
		}

		// create a receive thread
		DWORD dwThreadID;
		CreateThread(NULL, 0, ReceiveThread, NULL, 0, &dwThreadID);	
		// send an online msg to all friends
		TCHAR sz[20];
		strcpy(sz, "online msg");
		SendToAllFriends(sz, sizeof(sz));

		return 0; }
	case WM_DESTROY:
		WSACleanup();
		PostQuitMessage(0);
		return 0;
	}

	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

//////////////////////////////////////////////////////////////////////////

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, 
			int nShowCmd) {

	HWND hwnd;
	WNDCLASS wndclass;
	MSG msg;

    wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0 ;
    wndclass.cbWndExtra    = 0 ;
    wndclass.hInstance     = hInstance ;
    wndclass.hIcon         = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_ICON1)) ;
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
    wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
    wndclass.lpszMenuName  = MAKEINTRESOURCE(IDR_MAINFRAME);
    wndclass.lpszClassName = TEXT("Messenger") ;
	
	hInst = hInstance;

	if(!RegisterClass(&wndclass))
		MessageBox(NULL, "register failed", "error", 0);
	hwnd = CreateWindow(TEXT("Messenger"), TEXT("Messenger 1.0"), WS_OVERLAPPEDWINDOW, 
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
		NULL, NULL, hInstance, NULL);

	ShowWindow(hwnd, nShowCmd);
	UpdateWindow(hwnd);

	while(GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return 0;
}
	

⌨️ 快捷键说明

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