sdk笔记1

第二章

cxScreen = GetSystemMetrics (SM_CXSCREEN) ;   //得到系统的硬件的某些参数

cyScreen = GetSystemMetrics (SM_CYSCREEN) ;

RECT rt;

GetClientRect(hWnd, &rt); //得到客户区矩形区

//sprintf(buf,"   %d",4); // 格式化输出文本

wsprintf(buf,"   %d",6);

TextOut(hdc,10,10,buf,strlen(buf));

DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);

第三章

HICON LoadIcon(HINSTANCE hInstance,LPCTSTR lpIconName);  加载图标

第一个参数值为NULL,则是设置系统默认几种类型的图标

Getlasterror可用于函数调用失败时获得拓展的错误信息。

WM_DESTROY消息

WM_DESTROY消息是另一个重要消息。这一个消息指示,Windows正在根据使用者的指示关闭窗口。该消息是使用者单击Close按钮或者在程序的系统菜单上选择 Close时发生的(在本章的后面,我们将详细讨论WM_DESTROY消息是如何生效的)。

HELLOWIN通过呼叫PostQuitMessage以标准方式响应WM_DESTROY消息:

PostQuitMessage (0) ;

       

该函数在程序的消息队列中插入一个WM_QUIT消息。前面提到过,GetMessage对于除了WM_QUIT之外的从消息队列中取出的所有消息都传回非0值。而当GetMessage得到一个WM_QUIT消息时,它传回0。这将导致WinMain退出消息循环,并终止程序。然后程序执行下面的叙述:

return msg.wParam ;

       

结构的wParam字段是传递给PostQuitMessage函数的值(通常是0)。然后return叙述将退出WinMain并终止程序。

第四章

程序使用InvalidateRect或InvalidateRgn函数刻意产生WM_PAINT消息。

窗口消息处理程序可以通过呼叫InvalidateRect使显示区域内的矩形无效。如果消息队列中已经包含一个WM_PAINT消息,Windows将计算出新的无效矩形。否则,它将一个新的WM_PAINT消息放入消息队列中。在接收到WM_PAINT消息时,窗口消息处理程序可以取得无效矩形的坐标(我们马上就会看到这一点)。通过呼叫GetUpdateRect,可以在任何时候取得这些坐标。

在处理WM_PAINT消息处理期间,窗口消息处理程序在呼叫了BeginPaint之后,整个显示区域即变为有效。程序也可以通过呼叫ValidateRect函数使显示区域内的任意矩形区域变为有效。如果这呼叫具有令整个无效区域变为有效的效果,则目前队列中的任何WM_PAINT消息都将被删除。

wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 得到白色画刷

要使用GetTextMetrics函数,需要先定义一个结构变量(通常称为tm):

TEXTMETRIC tm ;    

在需要确定文字大小时,先取得设备内容句柄,再呼叫GetTextMetrics:

hdc = GetDC (hwnd) ;      

GetTextMetrics (hdc, &tm) ;

ReleaseDC (hwnd, hdc) ;

       

此后,您就可以查看文字尺寸结构中的值,并有可能保存其中的一些以备将来使用。

下面是取得系统字体的字符宽度和高度的WM_CREATE程序代码:

case WM_CREATE:  

    hdc = GetDC (hwnd) ;  

    GetTextMetrics (hdc, &tm) ;    

    cxChar = tm.tmAveCharWidth ;   

    cyChar = tm.tmHeight + tm.tmExternalLeading ;

ReleaseDC (hwnd, hdc) ;

    return 0 ;

hdc = GetDC (hwnd) ;

GetTextMetrics (hdc, &tm) ;                    

cxChar = tm.tmAveCharWidth ;                    

cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;  //得到大小写字母的平均宽度              

cyChar = tm.tmHeight + tm.tmExternalLeading ;                    

ReleaseDC (hwnd, hdc) ;

     UINT SetTextAlign( HDC hdc,UINT fMode);

该函数为指定设备环境设置文字对齐标志。

caseWM_SIZE:        // WM_SIZE传回客户区的尺寸

cxClient = LOWORD (lParam) ;             

cyClient = HIWORD (lParam) ;             

return 0 ;

在许多Windows程序中,WM_SIZE消息必然跟着一个WM_PAINT消息。为什么呢?因为在我们定义窗口类别时指定窗口类别样式为:

CS_HREDRAW | CS_VREDRAW

很容易在应用程序中包含水平或者垂直的滚动条,程序写作者只需要在CreateWindow的第三个参数中包括窗口样式(WS)标识符WS_VSCROLL(垂直卷动)和/或WS_HSCROLL(水平卷动)即可。这些卷动列通常放在窗口的右部和底部,伸展为显示区域的整个长度或宽度。显示区域不包含卷动列所占据的空间。对于特定的显示驱动程序和显示分辨率,垂直卷动列的宽度和水平卷动列的高度是恒定的。如果需要这些值,可以使用GetSystemMetrics呼叫来取得(如前面的程序那样)。

滚动条的范围和位置
SetScrollRange (hwnd, iBar, iMin, iMax, bRedraw) ;

BOOL SetScrollRange(   HWND hWnd, // 窗口句柄   

int nBar, // 滚动条类型   

int nMinPos, // 滚动条的最小位置   

int nMaxPos, // 滚动条的最大位置   

BOOL bRedraw // 重绘标志   );

int SetScrollPos(HWND hWnd,    // 窗体句柄     

int nBar,     // 滚动条     

int nPos,     // 滚动条的新位置     

BOOL bRedraw   // 重绘标志   );

为了给使用者提供回馈,Windows在您用鼠标拖动卷动方块时移动它,同时您的程序会收到SB_THUMBTRACK消息。然而,如果不通过呼叫SetScrollPos来处理SB_THUMBTRACK或SB_THUMBPOSITION消息,在使用者释放鼠标键后,卷动方块会迅速跳回原来的位置。

程序能够处理SB_THUMBTRACK或SB_THUMBPOSITION消息,但一般不同时处理两者。如果处理SB_THUMBTRACK消息,在使用者拖动卷动方块时您需要移动显示区域的内容。而如果处理SB_THUMBPOSITION消息,则只需在使用者停止拖动卷动方块时移动显示区域的内容。处理SB_THUMBTRACK消息更好一些(但更困难),对于某些型态的数据,您的程序可能很难跟上产生的消息。

如果您希望立即更新无效区域,可以在呼叫InvalidateRect之后呼叫UpdateWindow:

建立更好的滚动

Win32 API介绍的两个滚动条函数称作SetScrollInfo和GetScrollInfo。这些函数可以完成以前函数的全部功能,并增加了两个新特性。

SetScrollInfo (hwnd, iBar, &si, bRedraw) ;         

GetScrollInfo (hwnd, iBar, &si) ;

在呼叫SetScrollInfo或GetScrollInfo之前,必须将cbSize字段设定为结构的大小:

si.cbSize = sizeof (SCROLLINFO) ;

第五章

取得设备内容句柄

最常用的取得并释放设备内容句柄的方法是,在处理WM_PAINT消息时,使用BeginPaint和EndPaint呼叫:

hdc = BeginPaint (hwnd, &ps) ;         

其它行程序         

EndPaint (hwnd, &ps) ;

变量ps是型态为PAINTSTRUCT的结构,该结构的hdc字段是BeginPaint传回的设备内容句柄。 PAINTSTRUCT结构又包含一个名为rcPaint的RECT(矩形)结构,rcPaint定义一个包围窗口显示区域无效范围的矩形。使用从BeginPaint获得的设备内容句柄,只能在这个区域内绘图。BeginPaint呼叫使该区域有效。

Windows程序还可以在处理非WM_PAINT消息时取得设备内容句柄:

hdc = GetDC (hwnd) ;      

其它行程序       

ReleaseDC (hwnd, hdc) ;

Windows程序还可以取得适用于整个窗口(而不仅限于窗口的显示区域)的设备内容句柄:

hdc = GetWindowDC (hwnd) ;         

其它行程序         

ReleaseDC (hwnd, hdc) ;

这个设备内容除了显示区域之外,还包括窗口的标题列、菜单、滚动条和框架(frame)。GetWindowDC函数很少使用,如果想尝试用一用它,则必须拦截处理WM_NCPAINT消息,Windows使用该消息在窗口的非显示区域上绘图。

取得设备内容句柄的另一个更通用的函数是CreateDC:

hdc = CreateDC (pszDriver, pszDevice, pszOutput, pData) ;         

其它行程序         

DeleteDC (hdc) ;

例如,您可以通过下面的呼叫来取得整个屏幕的设备内容句柄:

hdc = CreateDC (TEXT ("DISPLAY"), NULL, NULL, NULL) ;

取得设备内容信息

一个设备内容通常是指一个实际显示设备,如视讯显示器和打印机。通常,您需要取得有关该设备的信息,包括显示器的大小(单位为图素或者实际长度单位)和色彩显示能力。您可以通过呼叫GetDeviceCaps(「取得设备功能」)函数来取得这些信息:

iValue = GetDeviceCaps (hdc, iIndex) ;

某些情况下,您可能想改变某些设备内容属性,用改变后的属性进行绘图,然后恢复原来的设备内容。要简化这一过程,可以通过如下呼叫来保存设备内容的状态:

idSaved = SaveDC (hdc) ;

现在,可以改变一些属性,在想要回到呼叫SaveDC前存在的设备内容时,呼叫:

RestoreDC (hdc, idSaved) ;

SetPixel (hdc, x, y, crColor) ;

GetPixel函数传回指定坐标处的图素颜色:

crColor = GetPixel (hdc, x, y) ;

画一条直线,必须呼叫两个函数。第一个函数指定了线的开始点,第二个函数指定了线的终点:

MoveToEx (hdc, xBeg, yBeg, NULL) ;         

LineTo (hdc, xEnd, yEnd) ;

如果您需要目前位置,就可以通过以下呼叫获得:

GetCurrentPositionEx (hdc, &pt) ;

当您要将数组中的点连接成线时,使用Polyline函数要简单得多。下面这条叙述画出与上面一段程序代码相同的矩形:

POINT apt[5] = { 100, 100, 200, 100, 200, 200, 100, 200, 100, 100 } ;

注意,最后一个点与第一个点相同。现在,只需要使用MoveToEx移到第一个点,并对后面的点使用LineTo:

Polyline (hdc, apt, 5) ;

MoveToEx (hdc, apt[0].x, apt[0].y, NULL) ;         

PolylineTo (hdc, apt + 1, 4) ;

PolylineTo有些不同,这个函数使用目前位置作为开始点,并将目前位置设定为最后一根线的终点。

边界框函数
问题在于,Rectangle、Ellipse、RoundRect、Chord和Pie函数严格来说不是画线函数。没错,这些函数是在画线,但它们同时又填入画刷填入一个封闭区域。

这些函数中最简单的就是画一个矩形:

您知道了如何画矩形,也就知道了如何画椭圆,因为它们使用的参数都是相同的:

Ellipse (hdc, xLeft, yTop, xRight, yBottom) ;

Rectangle (hdc, xLeft, yTop, xRight, yBottom) ;

画圆角矩形的函数使用与函数Rectangle及Ellipse函数相同的边界框,还包含另外两个参数:

RoundRect (hdc, xLeft, yTop, xRight, yBottom,                     xCornerEllipse, yCornerEllipse) ;

       

Arc、Chord和Pie函数都只要相同的参数:

Arc(hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd) ;     

Chord (hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd) ;     

Pie(hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd) ;

在Windows 98中,您不需要知道这些公式。要画一条或多条连接的贝塞尔曲线,只需呼叫:

PolyBezier (hdc, apt, iCount) ;    或PolyBezierTo (hdc, apt, iCount) ;

使用现有画笔(Stock Pens)
HPEN hPen ;

hPen = GetStockObject (WHITE_PEN) ;

SelectObject (hdc, hPen) ;

SelectObject的传回值是此呼叫前设备内容中的画笔句柄。如果启动一个新的设备内容并呼叫

hPen = SelectObject (hdc, GetStockobject (WHITE_PEN)) ;

画笔的建立、选择和删除
尽管使用现有画笔非常方便,但却受限于实心的黑画笔、实心的白画笔或者没有画笔这三种情况。如果想得到更丰富多彩的效果,就必须建立自己的画笔。

这一过程通常是:使用函数CreatePen或CreatePenIndirect建立一个「逻辑画笔」,这仅仅是对画笔的描述。这些函数传回逻辑画笔的句柄;然后,呼叫SelectObject将画笔选进设备内容。

CreatePen函数的语法形如:

hPen = CreatePen (iPenStyle, iWidth, crColor) ;

要使用CreatePenIndirect,首先定义一个LOGPEN型态的结构:

LOGPEN logpen ;

hPen = CreatePenIndirect (&logpen) ;

您可以通过如下呼叫来改变Windows用来填入空隙的背景色

SetBkColor (hdc, crColor) ;

通过将背景模式转换为TRANSPARENT,可以阻止Windows填入空隙:

SetBkMode (hdc, TRANSPARENT) ;

此后,Windows将忽略背景色,并且不填入空隙,可以通过呼叫GetBkMode来取得目前背景模式(TRANSPARENT或者OPAQUE)。

绘图方式

可以通过以下呼叫在设备内容中设定新的绘图模式:

SetROP2 (hdc, iDrawMode) ;

iDrawMode参数是表中「绘图模式」一栏中给出的值之一。您可以用函数:

iDrawMode = GetROP2 (hdc) ;

如果您想画一个没有边界框的图形,可以将NULL_PEN选进设备内容:

SelectObject (hdc, GetStockObject (NULL_PEN)) ;

如果您想画出图形的边界框,但不填入内部,则将NULL_BRUSH选进设备内容:

SelectObject (hdc, GetStockobject (NULL_BRUSH) ;

对于Polygon和PolyPolygon函数,Windows使用定义在设备内容中的目前画刷来填入这个带边界的区域。至于填入内部的方式,则取决于多边形填入方式,您可以用SetPolyFillMode函数来设定:

SetPolyFillMode (hdc, iMode) ;

FillRect (hdc, &rect, hBrush) ;         

FrameRect (hdc, &rect, hBrush) ;          I

nvertRect (hdc, &rect) ;

在这些函数中,rect参数是一个RECT型态的结构,它包含有4个字段:left、top、right和bottom。这个结构中的坐标被当作逻辑坐标。

FillRect用指定画刷来填入矩形(直到但不包含right和bottom坐标),该函数不需要先将画刷选进设备内容。

FrameRect使用画刷画矩形框,但是不填入矩形。使用画刷画矩形看起来有点奇怪,因为对于我们所介绍过的函数(如Rectangle),其边线都是用目前画笔绘制的。FrameRect允许使用者画一个不一定为纯色的矩形框。该边界框为一个逻辑单位元宽。如果逻辑单位大于设备单位,则边界框将会为2个图素宽或者更宽。

InvertRect将矩形中所有图素翻转,1转换成0,0转换为1,该函数将白色区域转变成黑色,黑色区域转变为白色,绿色区域转变成洋红色。

但是,通过呼叫SetRect函数,只需要一道叙述就可以得到同样的结果:

SetRect (&rect, xLeft, yTop, xRight, yBottom) ;

在您想要做以下事情之一时,可以很方便地选用其它8个函数:

· 将矩形沿x轴和y轴移动几个单元:
 

OffsetRect (&rect, x, y) ;

· 增减矩形的尺寸:
 

InflateRect (&rect, x, y) ;

· 矩形各字段设定为0:
 

SetRectEmpty (&rect) ;

· 将矩形复制给另一个矩形:
 

CopyRect (&DestRect, &SrcRect) ;

· 取得两个矩形的交集:
 

IntersectRect (&DestRect, &SrcRect1, &SrcRect2) ;

· 取得两个矩形的联集:
 

UnionRect (&DestRect, &SrcRect1, &SrcRect2) ;

· 确定矩形是否为空:
 

bEmpty = IsRectEmpty (&rect) ;

· 确定点是否在矩形内:
 

bInRect = PtInRect (&rect, point) ;

PeekMessage (&msg, NULL, 0, 0, PM_REMOVE) ;

前面的四个参数(一个指向MSG结构的指针、一个窗口句柄、两个值指示消息范围)与GetMessage的参数相同。将第二、三、四个参数设定为NULL或0时,表明我们想让PeekMessage传回程序中所有窗口的所有消息。如果要将消息从消息队列中删除,则将PeekMessage的最后一个参数设定为PM_REMOVE。如果您不希望删除消息,那么您可以将这个参数设定为PM_NOREMOVE。

while (TRUE)         

{              

if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))              

{                      

if (msg.message == WM_QUIT)                             

break ;                      

TranslateMessage (&msg) ;                      

DispatchMessage (&msg) ;              

}              

else              

{                      

// 完成某些工作的其它行程序              

}         

}         

return msg.wParam ;

本文出自 “不曾远去” 博客,谢绝转载!

你可能感兴趣的:(职场,sdk,休闲)