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?;
轉載于:https://blog.51cto.com/hantayi/384162
總結
- 上一篇: Aboutface3交互设计精髓笔记00
- 下一篇: 海思使用HiTool下载程序