在窗口显示文字和绘制图形文档格式.docx
《在窗口显示文字和绘制图形文档格式.docx》由会员分享,可在线阅读,更多相关《在窗口显示文字和绘制图形文档格式.docx(13页珍藏版)》请在冰点文库上搜索。
在接收到WM_PAINT消息时,窗口消息处理程序可以取得无效矩形的坐标(我们马上就会看到这一点)。
通过呼叫GetUpdateRect,可以在任何时候取得这些坐标。
在处理WM_PAINT消息处理期间,窗口消息处理程序在呼叫了BeginPaint之后,整个显示区域即变为有效。
程序也可以通过呼叫ValidateRect函数使显示区域内的任意矩形区域变为有效。
如果这呼叫具有令整个无效区域变为有效的效果,则目前队列中的任何WM_PAINT消息都将被删除
GDI相关的内容
要在窗口的显示区域绘图,可以使用Windows的图形设备接口(GDI)函数
(1).设备内容
句柄只不过是一个数值,Windows以它在内部使用对象。
程序写作者从Windows取得句柄,然后在其它函数中使用该句柄。
设备内容句柄是GDI函数的窗口「通行证」,有了这种设备内容句柄,程序写作者就能自如地在显示区域上绘图,使图形如自己所愿地变得好看或者难看。
设备内容(简称为「DC」)实际上是GDI内部保存的数据结构。
设备内容与特定的显示设备(如视讯显示器或打印机)相关。
对于视讯显示器,设备内容总是与显示器上的特定窗口相关。
设备内容中的有些值是图形「属性」,这些属性定义了GDI绘图函数工作的细节。
例如,对于TextOut,设备内容的属性确定了文字的颜色、文字的背景色、x坐标和y坐标映像到窗口的显示区域的方式,以及显示文字时Windows使用的字体。
当程序需要绘图时,它必须先取得设备内容句柄。
在取得了该句柄后,Windows用内定的属性值填入内部设备内容结构。
在后面的章节中您会看到,可以通过呼叫不同的GDI函数改变这些默认值。
利用其它的GDI函数可以取得这些属性的目前值。
当然,还有其它的GDI函数能够在窗口的显示区域真正地绘图。
当程序在显示区域绘图完毕后,它必须释放设备内容句柄。
句柄被程序释放后就不再有效,且不能再被使用。
程序必须在处理单个消息处理期间取得和释放句柄。
除了呼叫CreateDC()建立的设备内容之外,程序不能在两个消息之间保存其它设备内容句柄
(2)取得设备内容句柄的方法:
方法一:
caseWM_PAINT:
hdc=BeginPaint(hwnd,&
ps);
使用GDI函数
EndPaint(hwnd,&
return0;
在处理WM_PAINT消息时,使用这种方法。
它涉及BeginPaint和EndPaint两个函数,这两个函数需要窗口句柄(作为参数传给窗口消息处理程序)和PAINTSTRUCT结构的变量(在WINUSER.H表头文件中定义)的地址为参数
在处理WM_PAINT消息时,窗口消息处理程序首先呼叫BeginPaint。
BeginPaint函数一般在准备绘制时导致无效区域的背景被擦除。
该函数也填入ps结构的字段。
BeginPaint传回的值是设备内容句柄,这一传回值通常被保存在叫做hdc的变量中
HDC数据型态定义为32位的无正负号整数。
然后,程序就可以使用需要设备内容句柄的TextOut等GDI函数。
呼叫EndPaint即可释放设备内容句柄。
方法二:
hdc=GetDC(hwnd);
使用GDI函数
ReleaseDC(hwnd,hdc);
主要用来处理非WM_PAINT消息处理期间绘制显示区域的某个部分的;
主要步骤如下:
(1).得到窗口显示区域的设备内容句柄,可以呼叫GetDC来取得句柄,在使用完后呼叫ReleaseDC;
注意:
与从BeginPaint传回设备内容句柄不同,GetDC传回的设备内容句柄具有一个剪取矩形,它等于整个显示区域。
可以在显示区域的某一部分绘图,而不只是在无效矩形上绘图(如果确实存在无效矩形)。
与BeginPaint不同,GetDC不会使任何无效区域变为有效。
如果需要使整个显示区域有效,可以呼叫
ValidateRect(hwnd,NULL);
一般可以呼叫GetDC和ReleaseDC来对键盘消息(如在字处理程序中)和鼠标消息(如在画图程序中)作出反应。
此时,程序可以立刻根据使用者的键盘或鼠标输入来更新显示区域,而不需要考虑为了窗口的无效区域而使用WM_PAINT消息。
不过,一旦确实收到了WM_PAINT消息,程序就必须要收集足够的信息后才能更新显示。
与GetDC相似的函数是GetWindowDC。
GetDC传回用于写入窗口显示区域的设备内容句柄,而GetWindowDC传回写入整个窗口的设备内容句柄。
例如,您的程序可以使用从GetWindowDC传回的设备内容句柄在窗口的标题列上写入文字。
然而,程序同样也应该处理WM_NCPAINT(「非显示区域绘制」)消息
下面请看具体的示例(注意,其中的实现窗口部分的代码是重复前面的代码的,以后再说的时候就不全部写了,请大家参考前面的代码)
#include<
windows.h>
math.h>
#defineNUM1000
#definemyTWOPI(2*3.14159)
LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);
intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,PSTRszCmdLine,intiCmdShow)
{
staticTCHARszAppName[]=TEXT("
SinWave"
);
HWNDhwnd;
MSGmsg;
WNDCLASSwndclass;
wndclass.style=CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc=WndProc;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName=NULL;
wndclass.hInstance=hInstance;
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.lpszClassName=szAppName;
if(!
RegisterClass(&
wndclass))
{
MessageBox(NULL,TEXT("
ThisprogramrequiresWindowsNT!
"
),szAppName,MB_ICONERROR);
return0;
}
hwnd=CreateWindow(szAppName,
TEXT("
DrawSineWaveUsingPolyline"
),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
NULL,
hInstance,
NULL);
ShowWindow(hwnd,iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&
msg,NULL,0,0))
TranslateMessage(&
msg);
DispatchMessage(&
returnmsg.wParam;
}
LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)
staticintcxClient,cyClient;
HDChdc;
inti;
PAINTSTRUCTps;
POINTapt[NUM];
//定义1000组数据
TCHARszBuffer[40];
HPENhPen;
switch(message)
//处理WM_SIZE消息
caseWM_SIZE:
cxClient=LOWORD(lParam);
cyClient=HIWORD(lParam);
caseWM_PAINT:
hdc=BeginPaint(hwnd,&
ps);
//TCHARszBuffer[40];
注意此行要把szBuffer的定义放在消息处编译理的前面,不然编译会报错的;
SetTextColor(hdc,RGB(255,0,0));
//设置文字的背景色
SetBkColor(hdc,RGB(0,255,255));
/*
SetTextColor的MSDN文档
COLORREFSetTextColor(
HDChdc,//handletodevicecontext
COLORREFcrColor//textcolor
);
COLORREF的文档
WhenspecifyinganexplicitRGBcolor,theCOLORREFvaluehasthefollowinghexadecimalform:
0x00bbggrr
Thelow-orderbytecontainsavaluefortherelativeintensityofred;
thesecondbytecontainsavalueforgreen;
andthethirdbytecontainsavalueforblue.Thehigh-orderbytemustbezero.Themaximumvalueforasinglebyteis0xFF
TheRGBmacroselectsared,green,blue(RGB)colorbasedontheargumentssuppliedandthecolorcapabilitiesoftheoutputdevice.
COLORREFRGB(
BYTEbRed,//redcomponentofcolor
BYTEbGreen,//greencomponentofcolor
BYTEbBlue//bluecomponentofcolor
COLORREFSetBkColor(
HDChdc,//handleofdevicecontext
COLORREFcrColor//backgroundcolorvalue
*/
TextOut(hdc,20,20,szBuffer,
wsprintf(szBuffer,TEXT("
luliuyan!
))
看看MSDN的文档
intwsprintf(
LPTSTRlpOut,//pointertobufferforoutput
LPCTSTRlpFmt,//pointertoformat-controlstring
...//optionalarguments
返回的是字符串的长度;
BOOLTextOut(
intnXStart,//x-coordinateofstartingposition
intnYStart,//y-coordinateofstartingposition
LPCTSTRlpString,//pointertostring
intcbString//numberofcharactersinstring
//创建画笔
hPen=CreatePen(PS_SOLID,3,RGB(255,0,0));
//把画笔选入设备环境
SelectObject(hdc,hPen);
HPENCreatePen(
intfnPenStyle,//penstyle
intnWidth,//penwidth
COLORREFcrColor//pencolor
//画x方向的横线
MoveToEx(hdc,0,cyClient/2,NULL);
LineTo(hdc,cxClient,cyClient/2);
//画y方向的横线
MoveToEx(hdc,0,0,NULL);
LineTo(hdc,0,cyClient);
for(i=0;
i<
NUM;
i++)
//把横坐标等分成1000个点
apt[i].x=i*cxClient/NUM;
//根据横坐标计算纵坐标
apt[i].y=(int)(cyClient/2*(1-sin(myTWOPI*i/NUM)));
Polyline(hdc,apt,NUM);
//不要忘了清除画笔对象;
DeleteObject(hPen);
caseWM_DESTROY:
PostQuitMessage(0);
returnDefWindowProc(hwnd,message,wParam,lParam);
本文来自CSDN博客,转载请标明出处: