更新时间:2015-12-25 16:48:05浏览次数:1+次
我们先来看看实现的效果图:
InvalidateRect(hwnd,NULL,FALSE);
使客户区无效从而产生了客户区重绘,而在第三个参数中我们指明了FALSE表示不擦除背景,这样之前绘制的椭圆还是存在的。上一次的椭圆消失是因为他是白色的背景色,所以看不见了而已。如果对于InvalidateRect函数不明白,请阅读《InvalidateRect无效矩形的图文分析和在字符串中移动光标》和《InvalidateRect是否删除背景效果分析以及实现下划线删除线》,在此就不重复讲了。#include "windows.h"
#include <Windowsx.h>//GET_X_LPARAM,GET_Y_LPARAM宏需要这个头文件
#include <tchar.h>
// - 项目是Unicode字符集
HINSTANCE g_hInstance=NULL;
LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
TCHAR Info[100]=_T("C++技术网http://www.cjjjs.com");
RECT rect;
static POINT ptOld,ptNew;
static bool bIsFirst=true;
static TCHAR msg[100]=_T("");
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hwnd,&ps);
//绘制背景格子线,因为之前在鼠标移动时画了椭圆,所以此处的作画在椭圆上一层,所以这样椭圆看上去就是透明的。
GetClientRect(hwnd,&rect);
SelectObject(hdc,CreatePen(PS_SOLID,0,RGB(120,120,120)));//系统没有灰色的画笔,就只有自己创建咯
for (int i=0;i<rect.right;i+=50)
{
MoveToEx(hdc,i,0,NULL);
LineTo(hdc,i,rect.bottom);
}
for (int i=0;i<rect.bottom;i+=50)
{
MoveToEx(hdc,0,i,NULL);
LineTo(hdc,rect.right,i);
}
DeleteObject(SelectObject(hdc,GetStockObject(WHITE_PEN)));
//绘制提示文字,在格子线后画,就叠在线上,就看似不透明的效果。
if (!bIsFirst)//-在窗口第一次显示时,没有鼠标移动,不应该产生提示框,所以做一个判断
{
//画提示的文字
SetBkColor(hdc,RGB(255,244,10));//设置文字背景
wsprintf(msg,_T(" %d ,%d "),ptNew.x,ptNew.y);
SetTextColor(hdc,RGB(0,0,0));//设置文字颜色
TextOut(hdc,ptNew.x+15,ptNew.y+10,msg,lstrlen(msg));//输出文字
}
else
{
bIsFirst=false;
}
EndPaint(hwnd,&ps);
return 0;
case WM_MOUSEMOVE:
{
ptNew.x = GET_X_LPARAM(lParam);
ptNew.y = GET_Y_LPARAM(lParam);
//在这里绘制的椭圆,下一次的客户区重绘就会画在椭圆上,就实现椭圆背景的透明
hdc = GetDC(hwnd);
//-擦掉上次的椭圆
SelectObject(hdc,GetStockObject(WHITE_BRUSH));//创建画刷
SelectObject(hdc,GetStockObject(NULL_PEN));//需要设置空画笔占位,否则就用了默认的黑画笔画边框线了
Ellipse(hdc,ptOld.x,ptOld.y,ptOld.x+100,ptOld.y+35);//擦除上次的椭圆
//画本次的椭圆
SelectObject(hdc,CreateSolidBrush(RGB(200,150,10)));//创建画刷
SelectObject(hdc,GetStockObject(NULL_PEN));//不画边框线
Ellipse(hdc,ptNew.x,ptNew.y,ptNew.x+100,ptNew.y+35);//画提示框的椭圆背景
DeleteObject(SelectObject(hdc,GetStockObject(WHITE_BRUSH)));//删除画刷
//更新位置,本次的光标位置成为下一次的上一次光标位置
ptOld.x = ptNew.x;
ptOld.y = ptNew.y;
//额外的处理
InvalidateRect(hwnd,NULL,FALSE);//让客户区绘画,进而画出不透明的文字提示和透明的椭圆
SetTimer(hwnd,0,2000,NULL);//设置和重置计时器,这样鼠标只有停下才可以累积时间
ReleaseDC(hwnd,hdc);
}
return 0;
case WM_TIMER:
hdc = GetDC(hwnd);
//-擦掉上次的椭圆,因为椭圆区域涵盖了文字部分,所以文字不需要再擦除一次
SelectObject(hdc,GetStockObject(WHITE_BRUSH));//创建画刷
SelectObject(hdc,GetStockObject(NULL_PEN));//创建画刷
Ellipse(hdc,ptOld.x,ptOld.y,ptOld.x+100,ptOld.y+35);
//重新客户区所有的背景格子线,否则提示框擦除后就留下来空白痕迹
GetClientRect(hwnd,&rect);
SelectObject(hdc,CreatePen(PS_SOLID,0,RGB(120,120,120)));
for (int i=0;i<rect.right;i+=50)
{
MoveToEx(hdc,i,0,NULL);
LineTo(hdc,i,rect.bottom);
}
for (int i=0;i<rect.bottom;i+=50)
{
MoveToEx(hdc,0,i,NULL);
LineTo(hdc,rect.right,i);
}
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(WHITE_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;
}
g_hInstance = hInstance;
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;
}
相关资讯