更新时间:2015-12-17 20:30:06浏览次数:1+次
//COLORREF clr = GetPixel(hdc,GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam));//获得当前像素颜色
//int red = GetRValue(clr);
//int green = GetGValue(clr);
//int blue = GetBValue(clr);
//if(clr==0)return 0;//更快速的判断,黑色的三个分量都是0,合起来还是0
COLORREF clrClear = RGB(0,0,0);//合成创建一个黑色
for (int i=-10;i<=10;i++)
{
for (int j=-10;j<=10;j++)
{
SetPixel(hdc,GET_X_LPARAM(lParam)+i,GET_Y_LPARAM(lParam)+j,clrClear); //-单像素
}
}
运行后的效果如下:
红色画笔正常绘图绘制的粗线效果
for (int i=-10;i<=10;i++)
{
for (int j=-10;j<=10;j++)
{
//if(GetPixel(hdc,GET_X_LPARAM(lParam)+i,GET_Y_LPARAM(lParam)+j)==0)continue;//加入判断导致绘制擦除的黑色块的效率反而降低
SetPixel(hdc,GET_X_LPARAM(lParam)+i,GET_Y_LPARAM(lParam)+j,RGB(0,0,0)); //-单像素
}
}
第一个问题用判断的方式提升效率失败。有没有其他方式来优化呢?当然还有了。既然橡皮擦是块状的自然就想到了矩形咯。是的,我们就用画矩形的方式来代替自己用循环画点形成矩形,这样提高了效率,也就能够处理的更快。SelectObject(hdc,GetStockObject(BLACK_BRUSH));
如果是使用自己创建的画刷,那么一定要记得删除画刷,并且在删除前用其他的画刷替换,一般就用系统画刷设置为当前画刷即可。因为这里背景就是黑色的,所以就不用自己创建画刷了,这样不仅没有必要,反而降低了效率。系统画刷直接获取,只管使用,不要释放什么的。从这点来说,也是可以优化代码效率的。int size=50;//size*2+1就是整个的矩形块的大小,中心点有一个像素所以+1
Rectangle(hdc,GET_X_LPARAM(lParam)-size,GET_Y_LPARAM(lParam)-size,GET_X_LPARAM(lParam)+size,GET_Y_LPARAM(lParam)+size);
我们这里使用的是正方形,要实现圆形的橡皮擦,调用函数Ellipse即可,参数和Rectangle一模一样,而圆就是正方形的矩形的内切圆,所以其实这个参数就和矩形是一样的。然而我们却可以实现圆形橡皮擦了哦。我们可以看到效果图如下:
#include "windows.h"
#include <Windowsx.h>//GET_X_LPARAM,GET_Y_LPARAM宏需要这个头文件
#include <tchar.h>
// - 项目是Unicode字符集
LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
static bool bisPaint=false;
static bool bisClear=false;
TCHAR Info[100]=_T("【C++技术网http://www.cjjjs.com】");
int iRed,iGreen,iBlue;
static POINT ptOld;
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hwnd,&ps);//会清除无效矩形
TextOut(hdc,0,10,Info,lstrlen(Info));
EndPaint(hwnd,&ps);
return 0;
case WM_LBUTTONDOWN:
bisPaint=true;//开始作画
ptOld.x = GET_X_LPARAM(lParam);
ptOld.y = GET_Y_LPARAM(lParam);
return 0;
case WM_LBUTTONUP:
bisPaint=false;//松开鼠标,结束绘画
return 0;
case WM_RBUTTONDOWN:
bisClear=true;
ptOld.x = GET_X_LPARAM(lParam);
ptOld.y = GET_Y_LPARAM(lParam);
return 0;
case WM_RBUTTONUP:
bisClear=false;
return 0;
case WM_KEYDOWN:
InvalidateRect(hwnd,NULL,TRUE);
return 0;
case WM_MOUSEMOVE:
if(bisPaint)//如果按着鼠标时,表示在作画,因此可以开始绘制
{
hdc = GetDC(hwnd);
MoveToEx(hdc,ptOld.x,ptOld.y,NULL);
SelectObject(hdc,CreatePen(PS_SOLID,50,RGB(255,0,0)));
LineTo(hdc,GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam));
ptOld.x = GET_X_LPARAM(lParam);
ptOld.y = GET_Y_LPARAM(lParam);
ReleaseDC(hwnd,hdc);
}
if(bisClear)
{
//-擦除绘图
hdc = GetDC(hwnd);
//-造成擦除不流畅的代码
//COLORREF clr = GetPixel(hdc,GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam));//获得当前像素颜色
//int red = GetRValue(clr);
//int green = GetGValue(clr);
//int blue = GetBValue(clr);
//if(clr==0)return 0;//更快速的判断,黑色的三个分量都是0,合起来还是0
//从中心点(当前鼠标光标所在的点)向四周延伸两个像素
//for (int i=-10;i<=10;i++)
//{
// for (int j=-10;j<=10;j++)
// {
// //if(GetPixel(hdc,GET_X_LPARAM(lParam)+i,GET_Y_LPARAM(lParam)+j)==0)continue;//加入判断导致绘制擦除的黑色块的效率反而降低
// SetPixel(hdc,GET_X_LPARAM(lParam)+i,GET_Y_LPARAM(lParam)+j,RGB(0,0,0)); //-单像素
// }
//}
//-用圆形矩形区域填充来实现橡皮擦,提高效率
SelectObject(hdc,GetStockObject(BLACK_BRUSH));
int size=50;
//矩形橡皮擦
//Rectangle(hdc,GET_X_LPARAM(lParam)-size,GET_Y_LPARAM(lParam)-size,GET_X_LPARAM(lParam)+size,GET_Y_LPARAM(lParam)+size);
//圆形橡皮擦
Ellipse(hdc,GET_X_LPARAM(lParam)-size,GET_Y_LPARAM(lParam)-size,GET_X_LPARAM(lParam)+size,GET_Y_LPARAM(lParam)+size);
ReleaseDC(hwnd,hdc);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrev,LPSTR lpCmd,int iShow)
{
TCHAR ClassName[] = _T("MyClass");
TCHAR title1[] = _T("C++技术网http://www.cjjjs.com");
WNDCLASS wndClass;
wndClass.cbClsExtra=0;
wndClass.cbWndExtra=0;
wndClass.hbrBackground= (HBRUSH)GetStockObject(BLACK_BRUSH);
wndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndClass.hInstance = hInstance;
wndClass.lpfnWndProc = WinProc;
wndClass.lpszClassName = ClassName;
wndClass.lpszMenuName=NULL;
wndClass.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClass(&wndClass))return 0;
HWND hwnd = CreateWindow(ClassName,title1,WS_OVERLAPPEDWINDOW,0,0,440,400,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,SW_SHOWNORMAL);
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
相关资讯