功能设计如下:

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. Day 43数据库(Day1)

    创建表. create table student( id int not null auto_increment PRIMARY key, name archar() not null, age i ...

  2. Python廖雪峰学习笔记——单元测试

    定义:对一个模块.一个类.一个函数进行进行正确性检验的测试性工作.当我们对函数或者模块等进行修改时,单元测试就显得尤为重要. 单元测试 = 测试用例(用来测试的数据)+测试模块

  3. 文件操作(FILE)与常用文件操作函数

    文件 1.文件基本概念 C程序把文件分为ASCII文件和二进制文件,ASCII文件又称文本文件,二进制文件和文本文件(也称ASCII码文件)二进制文件中,数值型数据是以二进制形式存储的, 而在文本文件 ...

  4. poj3070 Fibonacci(矩阵快速幂)

    矩阵快速幂基本应用. 对于矩阵乘法与递推式之间的关系: 如:在斐波那契数列之中 f[i] = 1*f[i-1]+1*f[i-2]  f[i-1] = 1*f[i-1] + 0*f[i-2].即 所以, ...

  5. 本机的虚拟机执行ifconfig,显示不出ip的解决方法

    源于:https://blog.csdn.net/fuweihua123/article/details/78423715?locationNum=4&fps=1 本机的虚拟机执行ifconf ...

  6. zookeeper链接数导致kafka storm不能正常工作

    报错信息: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: org.apache ...

  7. 客户端集成IdentityServer4

    1. vs code 终端执行  dotnet new webapi --name ClientCredentialApi 2. 找到ValuesController.cs 引用  using Mic ...

  8. postgresql分区表探索(pg_pathman)

    使用场景 许多系统在在使用几年之后数据量不断膨胀,这个时候单表数据量超过2000w+,数据库的查询也越来越慢,而随着时间的推移许多历史数据的重要性可能逐渐下降.这时候就可以考虑使用分区表来将冷热数据分 ...

  9. rolling方式修改oplog

    在 3.4之前版本 , 修改oplog 是一个非常麻烦的事情, 要停数据库 , rolling方式适合 3.4 之前版本修改oplog的大小 1. 配置文件注释 replSet2. 配置文件 oplo ...

  10. IO概述、异常、File文件类_DAY19

    IO概述: 操作数据的工具 IO流,即数据流,数据像水流一样通过IO工具进行传输. 程序  <IO>   硬盘 绝对路径与相对路径 1:异常(理解) (1)就是程序的非正常情况. 异常相关 ...