功能设计如下:

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

  

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

  1. Creating Dialogbased Windows Application (1) / 创建基于对话框的Windows应用程序(一)新建窗体 / VC++, Windows

    创建基于对话框的Windows应用程序(一) —— 新建窗体 1.新建一个Visual C++的Empty Project.  2.在Solution Explorer中右键Add New Item, ...

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

    http://blog.163.com/wangxh_jy/blog/static/28233883201001581640283/ 关于详细的配置及程序运行截图,请下载:http://downloa ...

  3. Creating Dialogbased Windows Application (4) / 创建基于对话框的Windows应用程序(四)Edit Control、Combo Box的应用、Unicode转ANSI、Open File Dialog、文件读取、可变参数、文本框自动滚动 / VC++, Windows

    创建基于对话框的Windows应用程序(四)—— Edit Control.Combo Box的应用.Unicode转ANSI.Open File Dialog.文件读取.可变参数.自动滚动 之前的介 ...

  4. Creating Dialogbased Windows Application (3) / 创建基于对话框的Windows应用程序(三)Checkbox的应用、窗体置顶、设置图标 / VC++, Windows

    创建基于对话框的Windows应用程序(三) —— Checkbox的应用.窗体置顶.设置图标 上一节创建的窗体应用程序中,我们用到了Button和StaticText这两个控件.这一节中我们将学习使 ...

  5. Creating Dialogbased Windows Application (2) / 创建基于对话框的Windows应用程序(二)Button的应用、新建子窗体 / VC++, Windows

    创建基于对话框的Windows应用程序(二) —— Button的应用.新建子窗体 可以发现上一节创建的窗体中,点击OK和Cancel两个按钮是没有任何反应的.现在我们来为他们添加退出对话框的功能. ...

  6. VS2010 win32项目windows窗体程序 向导生成代码解析

    目录: 1.Win32项目的windows窗体程序的向导生成了如下代码 2.手工生成代码如下 3.当消息队列中没有消息需要处理,我们可以利用这段时间处理我们自己的任务 1.Win32项目的window ...

  7. VC菜菜鸟:建立第一个基于Visual C++的Windows窗口程序

    建立第一个基于VisualC++的Windows窗口程序: 发表于:http://blog.csdn.net/it1988888/article/details/10306585 a)执行命令:新建 ...

  8. C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案

    本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...

  9. Oracle 远程访问配置 在 Windows Forms 和 WPF 应用中使用 FontAwesome 图标 C#反序列化XML异常:在 XML文档(0, 0)中有一个错误“缺少根元素” C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper Decimal类型截取保留N位小数向上取, Decimal类型截取保留N位小数并且不进行四舍五入操作

    Oracle 远程访问配置   服务端配置 如果不想自己写,可以通过 Net Manager 来配置. 以下配置文件中的 localhost 改为 ip 地址,否则,远程不能访问. 1.网络监听配置 ...

随机推荐

  1. Day37 多进程

    什么是进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体: ...

  2. robot_framework Authorization 解决登录超时问题(token)

    写rf的接口时,遇到总是报错提示: 登录超时 解决过程: 1 . 通过对同一个接口进行手机抓包对比,发现该接口请求时,多了Authorization,需要HTTP Basic Authenticati ...

  3. springmvc执行流程详细介绍

    1.什么是MVC MVC是Model View Controller的缩写,它是一个设计模式 2.springmvc执行流程详细介绍 第一步:发起请求到前端控制器(DispatcherServlet) ...

  4. 用 TensorFlow 实现 k-means 聚类代码解析

    k-means 是聚类中比较简单的一种.用这个例子说一下感受一下 TensorFlow 的强大功能和语法. 一. TensorFlow 的安装 按照官网上的步骤一步一步来即可,我使用的是 virtua ...

  5. 从码农升为PM(节约成本)

    做为一个码农的潜规则,用户怎么要求怎么写,不论过程只论是否符合要求以及减少bug的存在,虽然bug随时会出现,这就是码农,一直以来都说码农分很多种但个人认为就是一种,原因是码农不懂的换位思考,不懂的在 ...

  6. Centos下用yum命令按照jdk

    一.查看是否已经安装了JDK #查看本机是否已经安装了jdk $ sudo yum list installed | grep java java--openjdk.x86_64 :.el7_6 @u ...

  7. 微服务是"银弹"吗?

    前言:所谓"银弹",本意是用金属银做成的子弹:在古老的传说里它是杀死狼人的有效武器.在著作<人月神话>也有描述.微服务是当前软件界流行的名词,那么它能成为像银弹一样厉害 ...

  8. sass安装及使用

    在Mac系统下,Ruby一般已内置在其中,如果您不能确认是否已安装,或者说你不知道你的Ruby使用的版本,你可以打开你的命令工具: $ ruby -v 安装sass 在大多数情况和大部分人群中,还是喜 ...

  9. 课程一(Neural Networks and Deep Learning),第一周(Introduction to Deep Learning)—— 1、经常提及的问题

    Frequently Asked Questions Congratulations to be part of the first class of the Deep Learning Specia ...

  10. 剑指offer三十九之平衡二叉树

    一.题目 输入一棵二叉树,判断该二叉树是否是平衡二叉树. 二.思路 详解代码. 三.代码 public class Solution {     //判断根节点左右子树的深度,高度差超过1,则不平衡 ...