LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
static BOOL fBlocking,fValidBox;
static POINT ptBeg,ptEnd,ptBoxBeg,ptBoxEnd;
HDC hdc;
PAINTSTRUCT ps;
switch(message)
{
case WM_LBUTTONDOWN:
ptBeg.x=ptEnd.x=LOWORD(lParam);
ptBeg.y=ptEnd.y=HIWORD(lParam);
DrawBoxOutline(hwnd,ptBeg,ptEnd);
//设置光标为IDC_CROSS,表示正在画矩形
SetCursor(LoadCursor(NULL,IDC_CROSS));
//标志,TRUE表示正在画
fBlocking=TRUE;
return 0;
case WM_MOUSEMOVE:
if(fBlocking)
{
//当鼠标移动时,设置光标为IDC_CROSS
SetCursor(LoadCursor(NULL,IDC_CROSS));
//当下面这一行注释点时,移动鼠标会出现下面图片的效果
DrawBoxOutline(hwnd,ptBeg,ptEnd);
ptEnd.x=LOWORD(lParam);
ptEnd.y=HIWORD(lParam);
//下面这一行也是会出现下面图片的效果
DrawBoxOutline(hwnd,ptBeg,ptEnd);
}
return 0;
case WM_LBUTTONUP:
if(fBlocking)
{
DrawBoxOutline(hwnd,ptBeg,ptEnd);
//用来保存最终的矩形
ptBoxBeg=ptBeg;
ptBoxEnd.x=LOWORD(lParam);
ptBoxEnd.y=HIWORD(lParam);
//光标还原
SetCursor(LoadCursor(NULL,IDC_ARROW));
fBlocking=FALSE;
fValidBox=TRUE;
//下面后调用WM_PAINT
InvalidateRect(hwnd,NULL,TRUE);
}
return 0;
case WM_CHAR:
//x1b是esc,实现效果,当正在画时,点一个esc会取消
if(fBlocking & (wParam=='\x1B'))
{
DrawBoxOutline(hwnd,ptBeg,ptEnd);
SetCursor(LoadCursor(NULL,IDC_ARROW));
fBlocking=FALSE;
}
return 0;
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
//这个是用来画鼠标松开时最终的矩形
if(fValidBox)
{
SelectObject(hdc,GetStockObject(BLACK_BRUSH));
Rectangle(hdc,ptBoxBeg.x,ptBoxBeg.y,ptBoxEnd.x,ptBoxEnd.y);
}
//这个是实现鼠标点下左键后,移动时候的效果,但是鼠标移动时没有调用这个,我认识无用
/*if(fBlocking)
{
SetROP2(hdc,R2_NOT);
SelectObject(hdc,GetStockObject(NULL_BRUSH));
Rectangle(hdc,ptBeg.x,ptBeg.y,ptEnd.x,ptEnd.y);
}*/
EndPaint(hwnd,&ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
上面代码有两个问题还没有搞清楚:
25---30行中有两个DrawBoxOutline,我试着去掉任何一个,但是效果都会变成下图这样。
我想应该跟WM_MOUSEMOVE有关,不能做到时时的来相应。
66-----72行的代码让我去掉了,我认识没有用,因为在WM_MOUSEMOVE中没有调用WM_PAINT,那段代码应该不会被执行。