功能设计如下:

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. python的super用法及含义

    注释:以下都是在python2.7版本验证的 总括:1.python解决二义性问题,经历了深度优先算法.广度优先算法.拓扑排序算法,目前python的版本都是使用拓扑算法(C3)    2.严谨sup ...

  2. git小白使用教程(一)

    本文所涉及命令基本可以涵盖日常开发场景, 对于开发者平时很少使用的命令不再列举,这样不至于让刚刚使用git的小伙伴们看的脑袋大...如有特殊使用可以联系我单独回复. 首先通过一张图了解git的工作流程 ...

  3. 【wireshark】插件开发(三):Lua插件 Dissector

    // TODO: 部分内容需要修改 1. 骨架 首先新建一个文件,命名为foo.lua,注意此文件的编码方式不能是带BOM的UTF8,否则wireshark加载它时会出错(不识别BOM): -- @b ...

  4. iOS开发总结--三方平台开发之分享

    1.前言 在公司参与了多个应用三方平台的开发,涉及微信.微博.QQ.Facebook.meetup等,总结一下一般的接入三方平台SDK方法. 2.接入三方SDK 任何应用要接入三方平台,都需要在该平台 ...

  5. Linux 基础命令 持续更新中...

    1.ls 显示当前文件/文件夹 显示文件大小: ls -lh  显示隐藏文件: ls -a 显示文件详细信息: ls -l (ll)2.pwd 显示当前所在路径 cat 显示当前文件下所有内容3.cd ...

  6. 解决input和button错位(不齐)问题

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Lingo 做线性规划 - Financial Applications

    Reference: <An Introduction to Management Science Quantitative Approaches to Decision Making, Rev ...

  8. python3 + zabbix api 的使用

    喜欢需要理由吗?需要吗?当然需要,zabbix的那么多功能足以让你喜欢她,现在还有zabbix API,zabbix真让我疯了,太牛逼了,太让人喜欢了.有zabbix API我们可以做很多,自己开发w ...

  9. Android RecyclerView的使用

    RecyclerView是什么? RecyclerView是一种新的视图组件,目标是为任何基于适配器的视图提供相似的渲染方式.它被作为ListView和GridView控件的继承者,在最新的suppo ...

  10. Javac语法糖之增强for循环

    加强的for循环有两种,遍历数组和实现了Iterable接口的容器.javac通过visitForeachLoop()方法来实现解语法糖,代码如下: /** Translate away the fo ...