功能设计如下:

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. Android应用安全防护和逆向分析 ——apk反编译

    概述 最近一直在学习Android应用安全相关和逆向分析的知识.现在移动app在安全方面是越来越重视了,特别是那些巨头企业涉及到钱的应用,那加密程度,简直是丧心病狂,密密麻麻.从这里可以看出,对于应用 ...

  2. (5)Oracle基础--约束

    · 约束的作用 <1> 定义规则 <2> 确保数据的完整性 · 约束 <1> 非空约束 ① 创建表时为字段添加非空约束 CREATE TABLE table_nam ...

  3. MySQL DeadLock故障排查过程

    [作者] 刘博:携程技术保障中心数据库高级经理,主要关注Sql server和Mysql的运维和故障处理. [环境] 版本号:5.6.21 隔离级别:REPEATABLE READ [问题描述] 接到 ...

  4. D08——C语言基础学PYTHON

    C语言基础学习PYTHON——基础学习D08 20180829内容纲要: socket网络编程 1  socket基础概念 2  socketserver 3  socket实现简单的SSH服务器端和 ...

  5. 【poj1850】 Code 数位dp+记忆化搜索

    题目大意:给你一个字符串,问你这个字符串的rank,如果这个字符串不合法,请直接输出0.(一个合法的字符串是对于∀i,有c[i]<c[i+1]) 字符串s的rank的计算方式:以字符串长度作为第 ...

  6. easyui 中iframe嵌套页面,大弹窗自适应居中的解决方法。$('#win').window()

    easyui 中iframe嵌套页面,大弹窗自适应居中的解决方法.$('#win').window() 以下是左边栏和头部外层遮罩显示和隐藏方法 /*外层 遮罩显示*/ function wrapMa ...

  7. LeNet - Python中的卷积神经网络

    本教程将  主要面向代码,  旨在帮助您 深入学习和卷积神经网络.由于这个意图,我  不会花很多时间讨论激活功能,池层或密集/完全连接的层 - 将来会有  很多教程在PyImageSearch博客上将 ...

  8. 剑指offer三十三之丑数

    一.题目 如果一个数的因子中,出去1和本身以外,质数因子只包含2.3和5,则把改数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含质数因子7. 习惯上我们把1当做是第一个 ...

  9. linux中的tar命令的使用

    参考网址: https://www.cnblogs.com/newcaoguo/p/5896975.html https://www.cnblogs.com/xccjmpc/p/6035397.htm ...

  10. 【Gitbook】实用配置及插件介绍

    前言 实际效果可以查看这里 github地址 配置 title 设置书本的标题 "title" : "Gitbook Use" author 作者的相关信息 & ...