代码如下:
#include <Windows.h>
#include <tchar.h>
#include <string>
#include <math.h>
using namespace std;
//声明回调函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
//窗口类名和窗口函数
const TCHAR szWindowClass[] = L"第一个窗口";
const TCHAR szWindowTitle[] = L"涂鸦";
const int IDM_TOPMOST=101;
const int IDMTIMER=1;
//判断安静是否按下的宏
#define KEY_DOWN(vk_code) (GetAsyncKeyState(vk_code) & 0x8000)
//WinMain函数,入口点
int WINAPI _tWinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,
LPTSTR lpCmdLine,int nCmdSHow)
{
//注册窗口类
WNDCLASSEX wcex={0};
wcex.cbSize=sizeof(WNDCLASSEX);
wcex.style=CS_HREDRAW|CS_VREDRAW;
wcex.lpfnWndProc=(WNDPROC)WndProc;
wcex.hInstance=hInstance;
wcex.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wcex.hCursor=LoadCursor(NULL,IDC_ARROW);
wcex.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wcex.lpszClassName=szWindowClass;
RegisterClassEx(&wcex);
//创建窗口
HWND hWnd = CreateWindow(
szWindowClass,
szWindowTitle,
WS_OVERLAPPEDWINDOW,
100,200,500,500,
HWND_DESKTOP,
NULL,
hInstance,
NULL
);
if(!hWnd) return FALSE;
//显示并更新窗口
ShowWindow(hWnd,nCmdSHow);
UpdateWindow(hWnd);
//进入消息循环
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
enum SCRAWLTYPE {SCRAWLINE,SCRAWRECTANGLE,SCRAWLELLIPSE,
SCRAWLCIRCIE};
TCHAR typeText[SCRAWLCIRCIE+1][10]={L"直线",L"矩形",L"椭圆",L"正圆"};
//在指定设备(hdc)上,用指定颜色(penColor)在矩形内(begin,end)绘制指定类型(type)的图形
void Draw(HDC hdc,POINTS begin,POINTS end,COLORREF penColor,SCRAWLTYPE type)
{
HPEN pen=CreatePen(PS_SOLID,1,penColor);
HPEN oldpen=(HPEN)SelectObject(hdc,pen);
switch(type){
case SCRAWLINE:
MoveToEx(hdc,begin.x,begin.y,NULL);
LineTo(hdc,end.x,end.y);
break;
case SCRAWRECTANGLE:
Rectangle(hdc,begin.x,begin.y,end.x,end.y);
break;
case SCRAWLELLIPSE:
Ellipse(hdc,begin.x,begin.y,end.x,end.y);
break;
case SCRAWLCIRCIE:
//计算半径
float r = sqrtf((end.x-begin.x)*(end.x-begin.x) + (end.y-begin.y)*(end.y-begin.y))/2;
//计算圆心
end.x=(begin.x+end.x)/2;
end.y=(begin.y+end.y)/2;
Ellipse(hdc,end.x-r,end.y-r,end.x+r,end.y+r);
break;
}
SelectObject(hdc,oldpen);
}
//窗口函数,用于消息处理
LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){
int nSel=0;
static SCRAWLTYPE type = SCRAWLINE;
static POINTS begin={0,0};
static COLORREF penColor=RGB(0,0,0);
static BOOL bTopMost=FALSE;
switch(msg){
case WM_KEYDOWN:
{
switch(wParam){
case 55: //按数字7,切换到直线
type = SCRAWLINE;
break;
case 56: //按数字8,切换到矩形
type=SCRAWRECTANGLE;
break;
case 57: //9,切换到椭圆
type=SCRAWLELLIPSE;
break;
case 48: //0,切换到圆
type=SCRAWLCIRCIE;
break;
case 0x52: //按字母R,选择红色
penColor=RGB(255,0,0);
break;
case 0x47: //G,绿色
penColor=RGB(0,255,0);
break;
case 0x42: //B,蓝色
penColor=RGB(0,0,255);
break;
case 0x4B: //K,黑色
penColor=RGB(0,0,0);
break;
}
}
case WM_LBUTTONDOWN:
{
begin=MAKEPOINTS(lParam); //获取起点坐标
return 0;
}
case WM_LBUTTONUP:
{
POINTS end=MAKEPOINTS(lParam); //获取终点坐标
//如果Ctrl键按下,则begin为所在矩形中心坐标,需要计算左上角坐标
if (wParam & MK_CONTROL)
{
begin.x=begin.x-(end.x-begin.x);
begin.y=begin.y-(end.y-end.y);
}
HDC hdc=GetDC(hWnd);
HBRUSH brush=(HBRUSH)SelectObject(hdc,(HBRUSH)GetStockObject(HOLLOW_BRUSH));
Draw(hdc,begin,end,penColor,type);
SelectObject(hdc,brush);
ReleaseDC(hWnd,hdc);
return 0;
}
case WM_CLOSE:
{
nSel=MessageBox(hWnd,L"你真的要退出吗?",szWindowTitle,MB_YESNO|MB_ICONQUESTION);
if(nSel==IDYES) DestroyWindow(hWnd);
return 0;
}
case WM_DESTROY:
{
KillTimer(hWnd,IDMTIMER);
PostQuitMessage(0);
return 0;
}
default:
return DefWindowProc(hWnd,msg,wParam,lParam);
}
}