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

📄 win32_drawing.cpp

📁 swain-0.5.2.zip的源代码,比较好用,希望大家喜欢.
💻 CPP
字号:
/*
This file is part of SWAIN (http://sourceforge.net/projects/swain).
Copyright (C) 2006  Daniel Lindstr鰉 and Daniel Nilsson

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA  02110-1301, USA.
*/
#include "stdafx.h"
#include "win32_drawing.h"
#include "win32_client.h"
#include "win32_buddies.h"
#include "../common/network.h"
#include "../common/coords.h"
#include "../common/ViewPort.h"
#include "../common/BitmapObject.h"
#include "../common/BackgroundObject.h"
#include "../common/ArrowObject.h"
#include "../common/PolylineObject.h"
#include "../common/BoundsObject.h"
#include "../common/ZoomTool.h"
#include "../common/PanTool.h"
#include "../common/PolylineTool.h"
#include "../common/ArrowTool.h"
#include "Win32Bitmap.h"

#define DRAG_THRESHOLD	8.0

#define SHMenuBar_GetMenu(hWndMB,idMenu) (HMENU)SendMessage((hWndMB), SHCMBM_GETSUBMENU, (WPARAM)0, (LPARAM)idMenu)

enum TOOLS {
	TOOL_ZOOM,
	TOOL_PAN,
	TOOL_LINE,
	TOOL_POINTER,
	NUM_TOOLS
};

// Global variables
HWND				g_hWndDrawingWindow;		// window handle

// Module variables
//static HWND g_hWndDrawingMenuBar;
static ViewPort *vp;
static Canvas *canvas;
static ObjectManager *objectman;
static Tool *tools[NUM_TOOLS];
static WCHAR *filename = NULL;
static ConnectionHandler *connhand;
static bool rotate;

static HANDLE ready_semaphore = NULL;
static bool ready_success = false;
static int peer_cid = -1;
static bool delete_file = false;
static bool followMe = false;

// Forward declaration of functions
static bool CreateDrawingWindow(void);
static void CleanUpSession(void);
static void ChangeTool(int idm);
static void ChangeColor(int idm);
static void ChangeFollowMe(void);

LRESULT CALLBACK DrawingWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
	POINT pt;
	static POINT oldpt;

	static BOOL mbdown = false;
//    static SHACTIVATEINFO s_sai;
	
    switch (message) 
    {
        case WM_COMMAND:
            wmId    = LOWORD(wParam); 
            wmEvent = HIWORD(wParam); 
            // Parse the menu selections:
            switch (wmId)
            {/*
                case IDM_DRAWING_MENU_EXIT:
					SendBye(peer_cid);					
                    SendMessage (hWnd, WM_CLOSE, 0, 0);				
                    break;
					*/
				case IDM_DRAWING_TOOLS_LINE:
				case IDM_DRAWING_TOOLS_POINTER:
				case IDM_DRAWING_TOOLS_PAN:
				case IDM_DRAWING_TOOLS_ZOOM:
					ChangeTool(wmId);
					break;
				case IDM_DRAWING_TOOLS_CLEARALL:
					if (objectman != NULL) {
						PacketClear *packet = new PacketClear();
						packet->setCId(peer_cid);
						connhand->sendPacket(packet);
						objectman->clearLayer(LAYER_NORMAL);
					}
					break;
				case IDM_DRAWING_TOOLS_FOLLOWME:
					ChangeFollowMe();
					break;
				case IDM_DRAWING_COLOR_BLACK:
					ChangeColor(IDM_DRAWING_COLOR_BLACK);
					break;
				case IDM_DRAWING_COLOR_WHITE:
					ChangeColor(IDM_DRAWING_COLOR_WHITE);
					break;
				case IDM_DRAWING_COLOR_RED:
					ChangeColor(IDM_DRAWING_COLOR_RED);
					break;
				case IDM_DRAWING_COLOR_GREEN:
					ChangeColor(IDM_DRAWING_COLOR_GREEN);
					break;
				case IDM_DRAWING_COLOR_BLUE:
					ChangeColor(IDM_DRAWING_COLOR_BLUE);
					break;
                default:
                    return DefWindowProc(hWnd, message, wParam, lParam);
            }
            break;
		case WM_PACKET_ARROW:
			{
				PacketArrow *packet = (PacketArrow *)lParam;
				FPOINT fp;
				packet->getPoint(&fp);
				ArrowObject *arrow = dynamic_cast<ArrowObject *>(objectman->getObject(packet->getOid()));
				if (arrow == NULL) {
					arrow = new ArrowObject(objectman, vp, &fp);
					objectman->addObject(arrow, LAYER_FRONT, packet->getOid());
				} else {
					arrow->setPoint(&fp);
				}
				delete packet;
			}
			break;
		case WM_PACKET_POLYLINE:
			{
				PacketPolyline *packet = (PacketPolyline *)lParam;
				FPOINT fp;
				packet->getPoint(&fp);
				PolylineObject *polyline = dynamic_cast<PolylineObject *>(objectman->getObject(packet->getOid()));
				if(polyline == NULL){
					polyline = new PolylineObject(vp, objectman, &fp, packet->getColor());
					objectman->addObject(polyline, LAYER_NORMAL, packet->getOid());
				}
				else{
					polyline->addPoint(&fp);
				}
				delete packet;
			}
			break;
		case WM_PACKET_CLEAR:
			{
				PacketClear *packet = (PacketClear *)lParam;
				objectman->clearLayer(LAYER_NORMAL);
				delete packet;
			}
			break;
		case WM_PACKET_BOUNDS:
			{
				static int bounds_oid = -1;
				PacketBounds *packet = (PacketBounds *)lParam;
				FRECT rect;
				packet->getBounds(&rect);
				bool follow = packet->getFollowMe();				
				BoundsObject *bo = dynamic_cast<BoundsObject *>(objectman->getObject(bounds_oid));
				if(bo == NULL){
					bo = new BoundsObject(objectman, vp, rect.left, rect.top, rect.right, rect.bottom);
					bounds_oid = objectman->addObject(bo, LAYER_FRONT);	
				}
				else{
					bo->changeBounds(rect.left, rect.top, rect.right, rect.bottom);
				}
				delete packet;
				if(follow){
					vp->setBounds(&rect);
					vp->getBounds(&rect);
					packet = new PacketBounds(rect, false);
					packet->setCId(peer_cid);
					connhand->sendPacket(packet);
				}
				
					

				
			}
			break;
        case WM_CREATE:
            break;
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            
			if (vp != NULL) {
				vp->redraw(&ps.rcPaint);
			}

            EndPaint(hWnd, &ps);
            break;

		case WM_LBUTTONDOWN:
			pt.x = (signed short)LOWORD(lParam);
			pt.y = (signed short)HIWORD(lParam);
			SetCapture(hWnd);
			mbdown = true;
			if (vp != NULL) {
				vp->mouseDown(&pt);
			}
			oldpt = pt;
			break;
		case WM_LBUTTONUP:
			pt.x = (signed short)LOWORD(lParam);
			pt.y = (signed short)HIWORD(lParam);
			ReleaseCapture();
			mbdown = false;
			if (vp != NULL) {
				vp->mouseUp(&pt);
			}
			break;
		case WM_MOUSEMOVE:
			pt.x = (signed short)LOWORD(lParam);
			pt.y = (signed short)HIWORD(lParam);
			if(mbdown && vp != NULL && distance(&oldpt, &pt) >= DRAG_THRESHOLD) {
				vp->mouseDragged(&pt);
				oldpt = pt;
			}
			break;
		case WM_CLOSE:
			SendBye(peer_cid);
			DestroyWindow(hWnd);
			break;
        case WM_DESTROY:
			CleanUpSession();
            break;

        case WM_ACTIVATE:
            break;
        case WM_SETTINGCHANGE:
            break;
        case WM_SIZE:
			if (vp != NULL) {
				vp->screenResized();

				FRECT rc;
				vp->getBounds(&rc);
				PacketBounds *pb = new PacketBounds(rc, followMe);
				pb->setCId(peer_cid);
				connhand->sendPacket(pb);
			}
			break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

static void ChangeTool(int idm) {
	static int oldidm = -1;
	int tool;
	HMENU hmnu;

	switch (idm) {
		case IDM_DRAWING_TOOLS_LINE: tool = TOOL_LINE; break;
		case IDM_DRAWING_TOOLS_PAN: tool = TOOL_PAN; break;
		case IDM_DRAWING_TOOLS_POINTER: tool = TOOL_POINTER; break;
		case IDM_DRAWING_TOOLS_ZOOM: tool = TOOL_ZOOM; break;
		default: break;
	}
	canvas->setTool(tools[tool]);
	
	hmnu = GetMenu(g_hWndDrawingWindow);
	if (oldidm != -1) {
		CheckMenuItem(hmnu, oldidm, MF_BYCOMMAND | MF_UNCHECKED);
	}
	CheckMenuItem(hmnu, idm, MF_BYCOMMAND | MF_CHECKED);
	oldidm = idm;
}

static void ChangeFollowMe(void) {
	HMENU hmnu;

	followMe = !followMe;

	((ZoomTool *)tools[TOOL_ZOOM])->setFollowMe(followMe);
	((PanTool *)tools[TOOL_PAN])->setFollowMe(followMe);

	hmnu = GetMenu(g_hWndDrawingWindow);
	CheckMenuItem(hmnu, IDM_DRAWING_TOOLS_FOLLOWME, MF_BYCOMMAND | followMe ? MF_CHECKED : MF_UNCHECKED);
}

static bool CreateDrawingWindow(void) {
    HWND hWnd = CreateWindow(szDrawingWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 600, 800, NULL, NULL, g_hInst, NULL);
    if (!hWnd)
    {
        return FALSE;
    }

	// HACK: Save the window handle in a global so it doesn't need to be passed around so much!
	g_hWndDrawingWindow = hWnd;

	return true;
}

void StartNewSession(ConnectionHandler *ch, ClientPacketHandler *cph,
					 int cid, IMAGE_TYPE imagetype){
	WCHAR fsFile[512] = L"";
	OPENFILENAME of;

	switch(imagetype){
	case(IMAGE_FILE):
		ZeroMemory(&of, sizeof(OPENFILENAME));
		of.lStructSize = sizeof(OPENFILENAME);
		of.hwndOwner = g_hWndMainWindow;
		of.lpstrFilter = L"Jpeg (*.jpg)\0*.JPG\0Bitmap (*.bmp)\0*.BMP\0Gif (*.gif)\0*.GIF\0"
			L"All images\0*.JPG;*.BMP;*.GIF\0Show all files (*.*)\0*.*\0";
		of.nFilterIndex = 4;
		//of.lpstrInitialDir = 
		of.lpstrFile = fsFile;
		of.nMaxFile = sizeof(fsFile);
		of.lpstrFileTitle = NULL;
		of.nMaxFileTitle = 0;
		if(GetOpenFileName(&of))
			filename = _wcsdup(fsFile);
		else{
			changeMyStatus(STATUS_ONLINE);
			return;
		}
		rotate = false;
		delete_file = false;
		break;
	case(IMAGE_NONE):
		filename = NULL;
		rotate = false;
		delete_file = false;
		break;
	}

	ready_semaphore = CreateSemaphore(NULL, 0, 1, NULL);
	do{
		ready_success = false;
		if (!ChooseBuddy(ch, cph, cid)) {
			changeMyStatus(STATUS_ONLINE);
			return;
		}

	}while((WaitForSingleObject(ready_semaphore, 20000) == WAIT_TIMEOUT ||!ready_success) && 
				MessageBox(NULL, L"Connection not accepted.", L"Error", MB_OK));
	PacketFile *pf = new PacketFile(filename, false);
	pf->setCId(peer_cid);
	ch->sendPacket(pf);
	CreateSession(ch, cph, 1);
	CloseHandle(ready_semaphore);
}

void CreateSession(ConnectionHandler *ch, ClientPacketHandler *cph, int clientid){
	FPOINT fp = {0, 0};

	if (!CreateDrawingWindow()) {
		changeMyStatus(STATUS_ONLINE);
		return;
	}
	printf("Creating session...");
	vp = new ViewPort(g_hWndDrawingWindow);
	objectman = new ObjectManager(clientid);
	canvas = new Canvas(objectman, vp);
	vp->setCanvas(canvas);
	vp->setOverzoom(3.0);
	vp->setZoomPan(1.0, &fp);
	objectman->setCanvas(canvas);
	connhand = ch;

	tools[TOOL_ZOOM] = new ZoomTool(vp, ch, peer_cid);
	tools[TOOL_PAN] = new PanTool(vp, ch, peer_cid);
	tools[TOOL_LINE] = new PolylineTool(vp, objectman, ch, peer_cid);
	tools[TOOL_POINTER] = new ArrowTool(objectman, vp, ch, peer_cid);
	ChangeTool(IDM_DRAWING_TOOLS_LINE);
	ChangeColor(IDM_DRAWING_COLOR_BLACK);
	Object *bgObj = NULL;
	RECT ext = { 0, 0, 1280, 1280 };
	if (filename) {
		try {
			bgObj = new BitmapObject(new Win32Bitmap(filename, rotate));
			((BitmapObject *)bgObj)->getPixelBounds(&ext);
		} catch (char *str) {
			printf("Error: %s\n", str);
			if(delete_file){
				DeleteFile(filename);
				filename = NULL;
			}
		}
	}
	if (!bgObj) {
		bgObj = new BackgroundObject();
	}
	FRECT fext;
	bgObj->getBounds(&fext);
	canvas->setExtents(&fext, &ext);
	objectman->addObject(bgObj, LAYER_BACK);
	ShowWindow(g_hWndMainWindow, SW_HIDE); //GetParent(g_hWndDrawingWindow)
	ShowWindow(g_hWndDrawingWindow, SW_SHOWNORMAL);
    UpdateWindow(g_hWndDrawingWindow);
}

static void CleanUpSession(void) {
	int i;
	if (filename && delete_file) {
		DeleteFile(filename);
		filename = NULL;
	}
	objectman->setCanvas(NULL);
	vp->setCanvas(NULL);
	delete canvas;
	canvas = NULL;
	delete objectman;
	objectman = NULL;
	delete vp;
	vp = NULL;
	for (i = 0; i < NUM_TOOLS; i++) {
		delete tools[i];
		tools[i] = NULL;
	}
	changeMyStatus(STATUS_ONLINE);
	ShowWindow(g_hWndMainWindow, SW_SHOWNORMAL);
}


void setSessionReady(int cid, bool success){
	peer_cid = cid;
	ready_success = success;
	ReleaseSemaphore(ready_semaphore, 1, NULL);
}


void joinSession(int cid, WCHAR *fname, bool rot){
	peer_cid = cid;
	filename = _wcsdup(fname);
	rotate = rot;
	wprintf(L"in join session: filename = %s.\n", filename);
	PostMessage(g_hWndMainWindow, WM_CREATESESSION, 0, 0);
	delete_file = true;
}

void closeSession(void){
	MessageBox(g_hWndDrawingWindow, L"Client left the session.", L"Disconnected", MB_OK);
	PostMessage(g_hWndDrawingWindow, WM_CLOSE, NULL, NULL); 
}


static void ChangeColor(int idm) {
	static int oldidm = -1;
	COLORREF color;
	HMENU hmnu;

	switch (idm) {
		case IDM_DRAWING_COLOR_BLACK: color = RGB(0, 0, 0); break;
		case IDM_DRAWING_COLOR_WHITE: color = RGB(255, 255, 255); break;
		case IDM_DRAWING_COLOR_RED: color = RGB(255, 0, 0); break;
		case IDM_DRAWING_COLOR_GREEN: color = RGB(0, 255, 0); break;
		case IDM_DRAWING_COLOR_BLUE: color = RGB(0, 0, 255); break;
		default: break;
	}
	((PolylineTool *)tools[TOOL_LINE])->setColor(color);

	hmnu = GetMenu(g_hWndDrawingWindow);
	if (oldidm != -1) {
		CheckMenuItem(hmnu, oldidm, MF_BYCOMMAND | MF_UNCHECKED);
	}
	CheckMenuItem(hmnu, idm, MF_BYCOMMAND | MF_CHECKED);
	oldidm = idm;
}

⌨️ 快捷键说明

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