基于win32的windows画板程序

功能设计如下:

1.Graphics菜单中可选择图形,支持Rectangle, Circle, Line,选择对应图形,则相应菜单项前面加上选中标志;

2.Options菜单中包含以下选项

  a.Color,设置颜色,选中此项,则弹出如下图所示对话框


  进入对话框时,默认值为当前颜色,单击"确定"后,则以选中颜色为当前前景色和填充色进行图形绘制

  

  b.Width 设置线条的宽度,选中此项则弹出如下对话框


进入对话框时,默认值为当前所使用的宽度值,单击"确定"按钮后,则以设定的值为当前宽度值进行图形绘制,宽度值范围1-10(注意:每次打开此对话框,显示当前正在使用的宽度值)

c.Fill和Opaque,设置填充的方式,Fill表示填充,Opaque表示透明,此两项为二选一,选中后,相应项目前面加上选中标志

3.绘制操作,单击鼠标左键,保持左键按下,移动鼠标,则在两点按下左键坐标点和当前鼠标坐标点间绘制出相应选中的图形。

4.Operation菜单

  a.Reverse菜单项(快捷键Ctrl + R),执行将图形沿水平方向翻转180度

  b.Reset菜单项(快捷键Ctrl + S),将图形从翻转状态恢复到正常状态

5.右键快捷菜单与4中a,b相同

程序源代码:

// exam.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <commdlg.h>
#include <commctrl.h>

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];								// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];								// The title bar text

CHOOSECOLOR  chc;
bool IsDraw=false;
bool IsReverse=false;
int g_iCount=0;

RECT rect1;
int Graphics=0;
COLORREF clref[16]={0x00ff0000};
bool IsFill=false;
int	iWidth=0;

struct DATASTORE		//图形数据存储结构
{
	RECT rect1;			//起点,终点
	int Graphics;		//图形形状
	COLORREF pColor;		//画笔颜色
	bool IsFill;			//画笔风格
	int iWidth;			//画笔宽度
	//int bColor;			//画刷颜色
};

struct DATASTORE DataStore[1000];	

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

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	// TODO: Place code here.
	MSG msg;
	HACCEL hAccelTable;

	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_EXAM, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

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

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

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

	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)
{
	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_EXAM);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= (LPCSTR)IDC_EXAM;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

	return RegisterClassEx(&wcex);
}

//
//   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;

   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;
   }

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

   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)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hDC;
	HBRUSH hBrush;
	HPEN hPen;
	HMENU hMenu;
	TCHAR szHello[MAX_LOADSTRING];
	LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

	WORD x,y;

	x = LOWORD(lParam);		//得到鼠标的位置.
	y = HIWORD(lParam);

	hMenu=GetMenu(hWnd);
	switch (message)
	{

		case WM_CREATE:
		//选择颜色通用对话框
		chc.lStructSize = sizeof(CHOOSECOLOR);		//结构大小
		chc.hwndOwner = hWnd;						//父窗口句柄
		chc.rgbResult = 0;							//设定默认颜色
		chc.lpCustColors = clref;					//指向用户自定义颜色数组的指针
		chc.Flags = 0;								//标志
		chc.lCustData = 0;
		chc.lpfnHook = NULL;						//钩子函数指针.同对话框处理函数功能一样
		chc.lpTemplateName = NULL;

		break;
		case WM_COMMAND:
			wmId    = LOWORD(wParam);
			wmEvent = HIWORD(wParam);
			// Parse the menu selections:
			switch (wmId)
			{
				case IDM_RECTANGLE:
					CheckMenuItem(hMenu,IDM_RECTANGLE,MF_CHECKED);
					CheckMenuItem(hMenu,IDM_CIRCLE,MF_UNCHECKED);
					CheckMenuItem(hMenu,IDM_LINE,MF_UNCHECKED);
					Graphics=2;
					break;
				case IDM_CIRCLE:
					CheckMenuItem(hMenu,IDM_CIRCLE,MF_CHECKED);
					CheckMenuItem(hMenu,IDM_RECTANGLE,MF_UNCHECKED);
					CheckMenuItem(hMenu,IDM_LINE,MF_UNCHECKED);
					Graphics=1;
					break;
				case IDM_LINE:
					CheckMenuItem(hMenu,IDM_LINE,MF_CHECKED);
					CheckMenuItem(hMenu,IDM_RECTANGLE,MF_UNCHECKED);
					CheckMenuItem(hMenu,IDM_CIRCLE,MF_UNCHECKED);
					Graphics=0;
					break;
				case IDM_COLOR:
					ChooseColor(&chc);
					break;
				case IDM_WIDTH:
					 DialogBox(hInst, (LPCTSTR)IDD_WIDTH, hWnd, (DLGPROC)Width);

					break;
				case IDM_FILL:
					CheckMenuItem(hMenu,IDM_FILL,MF_CHECKED);
					CheckMenuItem(hMenu,IDM_OPAQUE,MF_UNCHECKED);
					IsFill=true;
					break;
				case IDM_OPAQUE:
					CheckMenuItem(hMenu,IDM_OPAQUE,MF_CHECKED);
					CheckMenuItem(hMenu,IDM_FILL,MF_UNCHECKED);
					IsFill=false;

					break;
				case IDM_REVERSE:
					IsReverse=true;
					InvalidateRect(hWnd,NULL,TRUE);
					break;
				case IDM_RESET:
					IsReverse=false;
					InvalidateRect(hWnd,NULL,TRUE);
					break;

				case IDM_ABOUT:
				   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
				   break;
				case IDM_EXIT:
				   DestroyWindow(hWnd);
				   break;
				default:
				   return DefWindowProc(hWnd, message, wParam, lParam);
			}
			break;
		case WM_LBUTTONDOWN:
			IsDraw=true;
			rect1.left = x;
			rect1.top = y;
			//MoveToEx(hDC,rect1.left = x,rect1.top = y,NULL);
			break;
		case WM_LBUTTONUP:
			DataStore[g_iCount].rect1 = rect1;
			//DataStore[g_iCount].ptEnd = ptEnd;
			DataStore[g_iCount].Graphics = Graphics;
			DataStore[g_iCount].pColor = chc.rgbResult;
			DataStore[g_iCount].IsFill = IsFill;
			DataStore[g_iCount].iWidth = iWidth;
			//DataStore[g_iCount].bColor = bSelection;
			g_iCount++;
			IsDraw=false;
			break;
		case WM_MOUSEMOVE:
			rect1.right = x;
			rect1.bottom = y;
			if(IsDraw==true)
			{
				InvalidateRect(hWnd,NULL,TRUE);	//发出重绘信息.
				UpdateWindow(hWnd);
			}
			break;
		case WM_RBUTTONDOWN:
			POINT point;
			point.x=LOWORD(lParam);
			point.y=HIWORD(lParam);
			ClientToScreen(hWnd,&point);
			TrackPopupMenu(GetSubMenu(hMenu,3),TPM_LEFTALIGN,point.x,point.y,0,hWnd,NULL);
			break;
		case WM_PAINT:
			hDC = BeginPaint(hWnd, &ps);
			RECT rt;
			GetClientRect(hWnd, &rt);

			SetMapMode(hDC,MM_ANISOTROPIC);
			SetViewportOrgEx(hDC,(rt.left+rt.right)/2,(rt.bottom+rt.right)/2,NULL);
			SetViewportOrgEx(hDC,0,0,NULL); 

			int i;
			for(i = 0; i <g_iCount; i++)
			{
				if(IsReverse==true)
				{
					SetViewportExtEx(hDC,1,-1,0);
					SetViewportOrgEx(hDC,0,rt.bottom-rt.top ,NULL);
				}
				else
				{
					SetViewportExtEx(hDC,1,1,0);
					SetViewportOrgEx(hDC,0,0,NULL);
				}

				hPen=CreatePen(PS_SOLID,DataStore[i].iWidth,DataStore[i].pColor );
				if(DataStore[i].IsFill==true)
				{
					hBrush=CreateSolidBrush(DataStore[i].pColor);
				}
				else
				{
					hBrush=(HBRUSH)GetStockObject(NULL_BRUSH);
				}
				SelectObject(hDC,hBrush);
				SelectObject(hDC,hPen);

				if(DataStore[i].Graphics==0)
				{
					MoveToEx(hDC,DataStore[i].rect1.left,DataStore[i].rect1.top,NULL);
					LineTo(hDC,DataStore[i].rect1.right,DataStore[i].rect1.bottom);

				}
				if(DataStore[i].Graphics==1)
				{	

					Ellipse(hDC,DataStore[i].rect1.left,DataStore[i].rect1.top,DataStore[i].rect1.right,DataStore[i].rect1.bottom);
				}
				if(DataStore[i].Graphics==2)
				{	

					Rectangle(hDC,DataStore[i].rect1.left,DataStore[i].rect1.top,DataStore[i].rect1.right,DataStore[i].rect1.bottom);
				}
				DeleteObject(hPen);
				DeleteObject(hBrush);

			}

			hPen=CreatePen(PS_SOLID,iWidth,chc.rgbResult);
			if(IsFill==true)
			{
				hBrush=CreateSolidBrush(chc.rgbResult);
			}
			else
			{
				hBrush=(HBRUSH)GetStockObject(NULL_BRUSH);
			}
			SelectObject(hDC,hBrush);
			SelectObject(hDC,hPen);
			// TODO: Add any drawing code here...

			//DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
			if (IsDraw==true)
			{
				if(Graphics==0)
				{
					MoveToEx(hDC,rect1.left,rect1.top,NULL);
					LineTo(hDC,rect1.right,rect1.bottom);

				}
				if(Graphics==1)
				{	

					Ellipse(hDC,rect1.left,rect1.top,rect1.right,rect1.bottom);
				}
				if(Graphics==2)
				{	

					Rectangle(hDC,rect1.left,rect1.top,rect1.right,rect1.bottom);
				}
			}
			DeleteObject(hPen);
			DeleteObject(hBrush);

			EndPaint(hWnd, &ps);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_INITDIALOG:
				return TRUE;

		case WM_COMMAND:
			if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
			{
				EndDialog(hDlg, LOWORD(wParam));
				return TRUE;
			}
			break;
	}
    return FALSE;
}
LRESULT CALLBACK Width(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	HWND	hWndSlider=GetDlgItem(hDlg, IDC_SLIDER);
	switch (message)
	{

		case WM_INITDIALOG:
			SendMessage(hWndSlider, TBM_SETTICFREQ , 1, 0);
			SendMessage(hWndSlider, TBM_SETRANGE, 1, MAKELONG(1,10));

			return TRUE;
		case WM_SHOWWINDOW:
			SendMessageW(hWndSlider,TBM_SETPOS, 1,iWidth);//设置slider控件
			break;

		case WM_COMMAND:
			if (LOWORD(wParam) == IDOK)
			{

				iWidth= SendMessageW(hWndSlider, TBM_GETPOS, 0, 0);
				EndDialog(hDlg, LOWORD(wParam));

				return TRUE;
			}
			if (LOWORD(wParam) == IDCANCEL)
			{

				EndDialog(hDlg, LOWORD(wParam));

				return TRUE;
			}

			break;
	}
    return FALSE;
}

  

时间: 2024-10-14 07:14:24

基于win32的windows画板程序的相关文章

用Visual C#开发基于OpenCV的Windows应用程序

http://blog.163.com/wangxh_jy/blog/static/28233883201001581640283/ 关于详细的配置及程序运行截图,请下载:http://download.csdn.net/source/1127474名为<用Visual C#开发基于OpenCV的Windows应用程序>的文章. 由于百度允许的字数太少了,所以就不贴全部程序了.有需要源程序的话,请下载:http://download.csdn.net/source/1127477 下面是主要的

基于Debug模式windows应用程序app.config设置

介绍 当我们开发Windows窗体应用程序,我们肯定会利用App.config的.我们可以添加,修改和删除键/值对管理用户首选项.在这里,将会节省你的时间. 演示 这里有一个简单的Windows窗体应用程序来展示如何添加一个密钥对到App.config文件.我建立的Visual Studio 2015年这里面的Windows窗体应用程序. using System; using System.Collections.Generic; using System.ComponentModel; us

基于win32的socket编程及程序实现

初步研究了win32平台的Windows Sockets,它是Microsoft Windows的网络程序设计接口,它是从Berkeley Sockets扩展而来的,以动态链接库的形式提供给我们使用.包括流式套接字(提供面向连接.可靠的数据传输服务,数据无差错.无重复的发送,且按发送顺序接收.)和数据报套接字(提供无连接服务.数据包以独立包形式发送,不提供无错保证,数据可能丢失或重复,并且接收顺序混乱.).原始套接字. CS模型:在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户

基本的Windows应用程序 窗体创建

基本的Windows应用程序 转载:http://shiba.hpe.sh.cn/jiaoyanzu/WULI/Article1506 下面是一个完全可以运行的Windows程序,代码很简单,读者通过代码中的注释了解它们的含义.我们将在下一节详细讲解些代码.做为一个练习,我们建议读者在你的开发工具中创建一个工程,手工输入些代码,然后编译运行这个程序.注意,如果你使用的是Visual C++,那么在选择工程类型时必须是“Win32 application project”,而不能是“Win32 c

windows应用程序框架及实例

应用程序框架:同一类型应用程序的结构大致相同,并有很多相同的源代码,因此可以通过一个应用程序框架AFX(Application FrameWorks)编写同一类型应用程序的通用源代码. 主要向导: Datebase Project:创建数据库项目 MFC ActiveX Control Wizard:创建基于MFC的ActiveX控件 MFC AppWizard[dll]:创建基于MFC的动态链接库 MFC AppWizard[exe]:创建基于MFC的应用程序(最常用) New Databas

Windows应用程序的退出

Windows应用程序的退出 flyfish OnOK OnCancel EndDialog的关系 VC\atlmfc\src\mfc\dlgcore.cpp文件中 void CDialog::OnOK() { if (!UpdateData(TRUE)) { TRACE(traceAppMsg, 0, "UpdateData failed during dialog termination.\n"); // the UpdateData routine will set focus

Windows应用程序运行机制(笔记)

Windows应用程序:以windows作为平台运行的应用程序. API函数 API函数:windows提供了大量可以在应用程序中调用的,用C语言编写的函数. Windows API 函数的功能如下: 1.窗口管理函数:实现窗口的创建.移动和修改等功能. 2.图形设备函数:实现图形的绘制及操作功能,这类型函数的集合又叫做图形设备接口. 3.系统服务函数:实现与操作系统有关的一些功能. 窗口与句柄 在Windows应用程序中,窗口是通过窗口句柄(HWND)来标识的:要对某个窗口进行操作,就必须要得

Windows应用程序

  Windows应用程序是由一系列的消息处理 代码来实现的.这和传统的过程式编程方法很不一样,编程者只能够 预测用户所利用应用程序用户界面对象所进行的操作以及为这些操作 编写处理代码,却不可以这些操作在什么时候发生或者是以什么顺序 来发生,也就是说,我们不可能知道什么消息会在什么时候以什么顺 序来临. Windows应用程序基本流程:   Windows API:(windowsAppliacation Programming Interface. Windows 应用程序编程接口), API

基于EasyUI实现windows桌面

之前为大家介绍了 基于jquery tool实现的windows桌面效果,今天给大家带来一款基于EasyUI实现windows桌面.这款桌面适用浏览器:360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗. 不支持IE8及以下浏览器.效果图如下: 在线预览   源码下载 实现的代码. js代码: $(function () { $.messager.alert("站长素材", "欢迎访问站长素材,您现在可以体验改应用了,更多JS代码请继续关注&