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

📄 wince_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 "wince_drawing.h"
#include "wince_client.h"
#include "wince_buddies.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/ZoomTool.h"
#include "../common/PanTool.h"
#include "../common/PolylineTool.h"
#include "../common/ArrowTool.h"
#include "Camera.h"
#include "WinCEBitmap.h"

#define DRAG_THRESHOLD	4.0

// Choose what parts of the program to compile
#define USE_CAMERA

#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 Camera *camera;
static WCHAR *filename = NULL;
static ConnectionHandler *connhand;

static HANDLE ready_semaphore = NULL;
static bool ready_success = false;
static int peer_cid = -1;
static bool rotate;
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(void);
static void ChangeFollowMe(void);

void setSessionReady(int cid, bool success);

//deceleared in wince_client.cpp
void SendBye(int cid);


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_COLOR:
					ChangeColor();
					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;
                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:
			{
				PacketBounds *packet = (PacketBounds *)lParam;
				bool follow = packet->getFollowMe();
				if(follow){
					FRECT rect;
					packet->getBounds(&rect);
					vp->setBounds(&rect);
					delete packet;
					//the packet is returned just to update the xor-rect in win32 client.
					vp->getBounds(&rect);
					packet = new PacketBounds(rect, false);
					packet->setCId(peer_cid);
					connhand->sendPacket(packet);
				}
				else
					delete(packet);
			}
			break;
        case WM_CREATE:
            SHMENUBARINFO mbi;

            memset(&mbi, 0, sizeof(SHMENUBARINFO));
            mbi.cbSize     = sizeof(SHMENUBARINFO);
			mbi.dwFlags    = SHCMBF_COLORBK | SHCMBF_HIDESIPBUTTON;
            mbi.hwndParent = hWnd;
            mbi.nToolBarId = IDR_DRAWING_MENU;
            mbi.hInstRes   = g_hInst;
			mbi.nBmpId     = IDB_ICONS;
			mbi.cBmpImages = 17;
			mbi.clrBk      = RGB(0, 0, 0);

            if (!SHCreateMenuBar(&mbi)) 
            {
                g_hWndDrawingMenuBar = NULL;
            }
            else
            {
                g_hWndDrawingMenuBar = mbi.hwndMB;
            }

            // Initialize the shell activate info structure
            memset(&s_sai, 0, sizeof (s_sai));
            s_sai.cbSize = sizeof (s_sai);
			
            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:
			DestroyWindow(g_hWndDrawingWindow);
			break;
        case WM_DESTROY:
            CommandBar_Destroy(g_hWndDrawingMenuBar);
			CleanUpSession();
            break;

        case WM_ACTIVATE:
            // Notify shell of our activate message
            SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);
            break;
        case WM_SETTINGCHANGE:
            SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
            break;
#ifdef _DEVICE_RESOLUTION_AWARE
        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;
#endif
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

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

	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;
	}
	canvas->setTool(tools[tool]);

	TBBUTTONINFO tbbi = {0};
	tbbi.cbSize = sizeof(tbbi);
	tbbi.dwMask = TBIF_IMAGE;
	if (oldidm != -1) {
		SendMessage(g_hWndDrawingMenuBar, TB_GETBUTTONINFO, oldidm, (LPARAM)&tbbi);
		tbbi.iImage &= ~1;
		SendMessage(g_hWndDrawingMenuBar, TB_SETBUTTONINFO, oldidm, (LPARAM)&tbbi);
	}
	SendMessage(g_hWndDrawingMenuBar, TB_GETBUTTONINFO, idm, (LPARAM)&tbbi);
	tbbi.iImage |= 1;
	SendMessage(g_hWndDrawingMenuBar, TB_SETBUTTONINFO, idm, (LPARAM)&tbbi);
	oldidm = idm;
}

static void ChangeColor(void) {
	static int selected_color = 0;
	static const COLORREF colors[] = {
		RGB(0, 0, 0),
		RGB(255, 255, 255),
		RGB(255, 0, 0),
		RGB(0, 255, 0),
		RGB(0, 0, 255)
	};
	static const int num_colors = sizeof(colors) / sizeof(colors[0]);

	selected_color = (selected_color + 1) % num_colors;

	((PolylineTool *)tools[TOOL_LINE])->setColor(colors[selected_color]);

	TBBUTTONINFO tbbi = {0};
	tbbi.cbSize = sizeof(tbbi);
	tbbi.dwMask = TBIF_IMAGE;
	tbbi.iImage = 10 + selected_color;
	SendMessage(g_hWndDrawingMenuBar, TB_SETBUTTONINFO, IDM_DRAWING_COLOR, (LPARAM)&tbbi);
}

static void ChangeFollowMe(void) {
	followMe = !followMe;

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

	TBBUTTONINFO tbbi = {0};
	tbbi.cbSize = sizeof(tbbi);
	tbbi.dwMask = TBIF_IMAGE;
	tbbi.iImage = followMe ? 16 : 15;
	SendMessage(g_hWndDrawingMenuBar, TB_SETBUTTONINFO, IDM_DRAWING_TOOLS_FOLLOWME, (LPARAM)&tbbi);
}

static bool CreateDrawingWindow(void) {
    HWND hWnd = CreateWindow(szDrawingWindowClass, szTitle, WS_VISIBLE,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 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;

	// Go fullscreen and adjust size to make room for toolbar.
	SHFullScreen(hWnd, SHFS_HIDETASKBAR);
	RECT rc;
    GetWindowRect(hWnd, &rc);
	rc.top = 0;
	if (g_hWndDrawingMenuBar)
    {
        RECT rcMenuBar;

        GetWindowRect(g_hWndDrawingMenuBar, &rcMenuBar);
        rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top);
    }
	MoveWindow(hWnd, rc.left, rc.top, rc.right, rc.bottom, TRUE); 
	return true;
}

void StartNewSession(ConnectionHandler *ch, ClientPacketHandler *cph, int cid, IMAGE_TYPE imagetype) {
	WCHAR fsFile[512] = L"";
	OPENFILENAME of;
	switch(imagetype){
	case(IMAGE_CAMERA):
		camera = new Camera(g_hWndMainWindow);
		filename = camera->Start();
		rotate = true;
		if(filename != NULL)
			delete_file = true;
		else
			return;
		break;
	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
			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)) {
			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, rotate);
	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()) {
		return;
	}
	printf("Creating session...");
	vp = new ViewPort(g_hWndDrawingWindow);
	objectman = new ObjectManager(clientid);
	canvas = new Canvas(objectman, vp);
	vp->setCanvas(canvas);
	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);
	Object *bgObj = NULL;
	RECT ext = { 0, 0, 1280, 1280 };
	if (filename) {
		try {
			bgObj = new BitmapObject(new WinCEBitmap(filename, rotate));
			((BitmapObject *)bgObj)->getPixelBounds(&ext);
		} catch (char *str) {
			printf("Error: %s\n", str);
			if(delete_file){
				DeleteFile(filename);
				filename = NULL;
			}
		}
	}
	if (!filename) {
		bgObj = new BackgroundObject();
	}
	FRECT fext;
	bgObj->getBounds(&fext);
	canvas->setExtents(&fext, &ext);
	objectman->addObject(bgObj, LAYER_BACK);
	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;
	}
#ifdef USE_CAMERA
	delete camera;
#endif
}


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);
	if(filename != NULL)
		delete_file = true;
	rotate = rot;
	wprintf(L"in join session: filename = %s.\n", filename);
	PostMessage(g_hWndMainWindow, WM_CREATESESSION, 0, 0);
}

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

⌨️ 快捷键说明

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