WINDOWS程序设计 复习(2)

我已经复习了文本输出以及一些窗口的一些知识,这次我复习绘图基础,键盘以及鼠标。编程,就是要多编写容易提升,现在才懂那么一点点,不过什么时候也不晚,哈哈,知识的多寡从来不是决定性因素,只有一颗什么样的内心才是决定性因素,这是我认为。
绘图这东西,感觉好复杂,各种设置。书上也只是入门而已。
图形设备接口(Graphics Device Interface,GDI)是一个在显示器和打印机上显示图形的子系统。
先把书上的专业名词和一些比较需要知道的知识整理出来。
使用GDI的函数或者说顺序
获取(或建立)和释放(或销毁)设备环境的函数//绘制时需要使用一个环境句柄比如beginPaint
获取环境信息的函数//比如GetTextMetrics()获取字体大小的信息
绘图函数//...
设置和获取设备环境属性的函数
使用GDI"对象"的函数


光栅设备(raster device)大多数PC输出设备,他们将凸显个表示成以点的形式构成的矩阵
矢量设备(vector device)指绘图机,使用线条来绘制图形
基本图形,线条和曲线,可悲填充的封闭区域,位图(一个二维数组,每一个元素显示设备上的一个像素),文本
图元文件//图元文件是以二进制形式储存的GDI命令的集合。
区域//一个任意形状的封闭图形,通常可以表示为由一系列简单区域进行布尔运算后得出的结果
路径//路径是储存在GDI内部直线和曲线的集合
裁剪//绘图被限制在客户区的一个特定的空间位置
调色板,打印。
映射模式(mapping mode)和转换(transform)//这个是非常有意思,也是我一开始难理解的地方,我就先开始复习它。
设备坐标系统//WINDOWS会把在GDI函数中指定的逻辑坐标转换为设备坐标。
有二种函数对于设备坐标系统,
1.与窗口无关的函数
2.必须根据屏幕上的点移动或寻找窗口的函数
然后了我们就由对于全窗口和客户区获取,又有区别了
GetDC与BeginPaint都是客户区或者说会将逻辑坐标转换为客户区坐标
GetWindowDC则是全窗口获取
上述知识,我们进一步来学习映射模式在《WINDOWS程序设计》中有2个概念可能和别的书不同
视口,以设备坐标(像素)的形式指定
窗口,以逻辑坐标的形式指定
窗口转视口的公式(这个公式,其实对于不想对界面要求很高的人,没什么大用,并且感觉会很快忘记)
xViewport=(xWindow-xWinOrg)*xViewExt/xWinExt+xViewORG
yViewport=(yWindow-yWinOrg)*yViewExt/yWinExt+yViewOrg
(xWindow,yWindow)是一个带转换的逻辑点坐标,(xViewPort,yViewport)是转换后的设别坐标点坐标 
视口转窗口的公式
xWindow=(xViewport-xViewOrg)*xWindExt/xViewExt+xWinOrg
yWindow=(yViewport-yViewOrg)*yWindExt/yViewExt+yWinOrg
将设备点转换为逻辑点
DPtoLP(hdc,pPoints,iNumber); //pPoints是一个指针,指向一个POINT结构的数组。iNumber为转换点的个数
LPtoDP(hdc,pPoints,iNumber);//同上
下面就开始了一个映射模式的选择 
映射模式 (8种映射) 逻辑单位X轴增加的方向 Y轴增加的方向
MM_TEXT 像素                        
MM_LOMETRIC 0.1mm
MM_HIMETRIC 0.01mm
MM_LOENGLISH 0.01in = 0.254mm
MM_HIENGLISH
0.001in
MM_TWIPS
1/1440in
MM_ISOTROPIC 任意( x = y )可选
可选
MM_ANISOTROPIC
任意( x = y ) 可选可选
上面这个图我是从http://blog.csdn.net/y_bma/article/details/21599471这个博客转过来的。
至于有什么区别了,我觉得说不清楚,直接给上测试代码吧
#include
 

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;


int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("WhatSize") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;
     
     wndclass.style         = CS_HREDRAW | CS_VREDRAW;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
     
     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
     
     hwnd = CreateWindow (szAppName, TEXT ("What Size is the Window?"),
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;
     
     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;
     
     while (GetMessage (&msg, NULL, 0, 0))
     {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
     }
     return msg.wParam ;
}


void Show (HWND hwnd, HDC hdc, int xText, int yText, int iMapMode,
           TCHAR * szMapMode)
{
     TCHAR szBuffer [60] ;
     RECT  rect ;
     
     SaveDC (hdc) ;//保存设备上下文,可以用RestoreDC恢复
     
     SetMapMode (hdc, iMapMode) ;//设置映射模式
     GetClientRect (hwnd, &rect) ;//获取客户区
     DPtoLP (hdc, (PPOINT) &rect, 2) ;//设备点转换为逻辑蒂娜
     
     RestoreDC (hdc, -1) ;//恢复设备上下文
     
     TextOut (hdc, xText, yText, szBuffer,
              wsprintf (szBuffer, TEXT ("%-20s %7d %7d %7d %7d"), szMapMode,
              rect.left, rect.right, rect.top, rect.bottom)) ;
}  


LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static TCHAR szHeading [] =
          TEXT ("Mapping Mode            Left   Right     Top  Bottom") ;
     static TCHAR szUndLine [] = 
          TEXT ("------------            ----   -----     ---  ------") ;
     static int   cxChar, cyChar ;
     HDC          hdc ;
     PAINTSTRUCT  ps ;
     TEXTMETRIC   tm ;
     
     switch (message)
     {
     case WM_CREATE:
          hdc = GetDC (hwnd) ;
          SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
          
          GetTextMetrics (hdc, &tm) ;//得到字体的信息
          cxChar = tm.tmAveCharWidth ;//字体宽度
          cyChar = tm.tmHeight + tm.tmExternalLeading ;//字体高度
          
          ReleaseDC (hwnd, hdc) ;
          return 0 ;
          
     case WM_PAINT:
          hdc = BeginPaint (hwnd, &ps) ;
          SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;//对设备上下文设置字体为等宽
          
          SetMapMode (hdc, MM_ANISOTROPIC) ;
          SetWindowExtEx (hdc, 1, 1, NULL) ;//设置接受单位的一个范围
          SetViewportExtEx (hdc, cxChar, cyChar, NULL) ;//设备环境的范围
          
          TextOut (hdc, 1, 1, szHeading, lstrlen (szHeading)) ;
          TextOut (hdc, 1, 2, szUndLine, lstrlen (szUndLine)) ;
          
          Show (hwnd, hdc, 1, 3, MM_TEXT,      TEXT ("TEXT (pixels)")) ;
          Show (hwnd, hdc, 1, 4, MM_LOMETRIC,  TEXT ("LOMETRIC (.1 mm)")) ;
          Show (hwnd, hdc, 1, 5, MM_HIMETRIC,  TEXT ("HIMETRIC (.01 mm)")) ;
          Show (hwnd, hdc, 1, 6, MM_LOENGLISH, TEXT ("LOENGLISH (.01 in)")) ;
          Show (hwnd, hdc, 1, 7, MM_HIENGLISH, TEXT ("HIENGLISH (.001 in)")) ;
          Show (hwnd, hdc, 1, 8, MM_TWIPS,     TEXT ("TWIPS (1/1440 in)")) ;
          
          EndPaint (hwnd, &ps) ;
          return 0 ;
          
     case WM_DESTROY:
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}


我觉得上面解释的也比较含糊,可以看上面的链接。但是很多函数都可以在上面看到。


再就是具体的绘制函数
SetPixel(hdc,x,y,crColor)//设置像素点的特定颜色
GetPixel(hdc,x,y)//返回指定坐标位置的像素颜色;


LineTo//画直线
Polyline和PolylineTo//画一条由多条首尾相连的直线构成的折线
PolyPolyline//画多条折线
Arc//画椭圆弧线
PolyBezier和PolyBezierTo//画贝塞尔样曲线
ArcTo和AngleArc//画椭圆弧线
PolyDraw//画多条贝塞尔样条曲线或者一条由多条首尾相连直线构成的折线
Rectangle//画矩形
Ellipse//画椭圆
RoundRect//画圆角矩形
Pie//画椭圆的一部分,使其看起来像一个扇形
Chord//画出由弦割出的部分椭圆,形状呈弓形


使用画笔(支持3种默认颜色实心白色,实心黑色和没有画笔)
HPEN hPen;
hPen=GetStockObject(WHITE_PEN);
SelectObejct(hdc,hPen);//SelectObject(hdc,GetStockObject(WHITE_PEN))把画笔颜色选入设备上下文
创建画笔(不满足那些默认画笔)
hPen=CreatePen(iPenStyle,iWidth,crColor);//iPenStyle决定是实线,虚线或者点线 iWidth是画笔宽度  crColor是决定颜色


填充空隙SetBkColor(hdc,crColor);//改变Windows填充空隙的背景颜色
由一个方法可以阻止填充颜色,就是将背景设置为透明
SetBkMode(hdc,TRANSPARENT);


对于画刷的操作就是HPEN改为HBRUSH。
Polygon填充有一个特别的规则,就是填充的时候有些特别,不影响大概就不用考虑,哈哈。
嗯还是复习下,就是分为ALTERNATE和WINDIG模式。
SetPolyFillMode(hdc,iMode);//iMode就是模式
ALTERNATE模式,是否被填充,设想从区域内一个点画一个无穷远的射线,奇数填充,偶数不填。
WINDIG模式,要确定一个区域十分应该被填充,设想从区域内的一个点画一条伸向无穷远的射线,奇数填充,偶数要考虑边框方向,不同方向的边框线的数目相等,不填充,否则就填充。


好啦好啦,来复习键盘和鼠标啦啦啦啦。
键盘肯定有键盘消息啦,接受到这个键盘事件的窗口称为有输入焦点的窗口
键盘消息分为击键和字符两种。//击键就是按下与释放,或者说一些组合键产生的消息
非系统击键 WM_KEYDOWN WM_KEYUP(按下与释放)
系统击键 WM_SYSKEYDOWN WM_SYSKEYUP


wParam参数包含了虚拟键代码,lParam参数包含了帮助理解击键的其他有用消息


通过GetKeyState();//可以知道释放有转义键
可以用SenMessage(hwnd,message,wParam,lParam);//他携带了传给窗口过程的参数
如果我要写一个个性化的TXT程序了,如何捕捉字符了
这个时候就出来了字符消息
非系统字符 WM_CHAR WM_DEADCHAR
系统字符    WM_SYSCHAR      WM_SYSDEADCHAR
Get
GetKeyNameText(LONG lParam,LPTSTR  lpString,int Size);
//lParam指定被处理的键盘消息(例如WM_KEYDOWN)的第二个参数
//LpString:指向接受键名的缓冲区的指针。
//nSize:指定键名的最大字符长度,包括空结束符。(该参数值应与LpString参数指定的缓冲区的大小相等)。
还有一些插入符号函数
CreateCaret//创建和窗口关联的插入符号
SetCarePos//设置窗口内的插入符号的位置
ShowCaret//显示插入符号
HideCaret//隐藏插入符号
DestroyCaret//销毁插入符号


嗯继续鼠标
客户区鼠标消息
左键WM_LBUTTONDOWN WM_LBUTTONUP WM_LBUTTONDBLCLK
中键WM_MBUTTONDOWN WM_MBUTTONUP WM_MBUTTONDBLCLK
右键WM_RBUTTONDOWN WM_RBUTTONUP WM_RBUTTONDBLCLK
移动会产生WM_MOUSEMOVE来获取然后使用LOWROD(lParam)和HIWORD(lParam)来得到鼠标地点
双击可以再wndclass.style=CS_DBLCLKS就会改变一些消息
WM_LBUTTONDOWN WM_LBUTTONDOWN
WM_LBUTTONUP WM_LBUTTONUP
WM_LBUTTONDOWN WM_LBUTTONDBLCLK
WM_LBUTTONUP WM_LBUTTONUP
非客户的消息几乎与其全部对应


左键WM_NCLBUTTONDOWN WM_NCLBUTTONUP WM_NCLBUTTONDBLCLK
中键WM_NCMBUTTONDOWN WM_NCMBUTTONUP WM_NCMBUTTONDBLCLK
右键WM_NCRBUTTONDOWN WM_NCRBUTTONUP WM_NCRBUTTONDBLCLK
其他照旧你懂的
还有一个ShowCursor(TRUE);//有一个计数就是当计数非0才会显示鼠标,默认初始化为0,。参数为TRUE为+1参数为FALSE-1
GetCursorPos(&pt)//可以获取鼠标位置
SetCursorPos(x,y);//设置鼠标位置
当你从客户区或者非客户区到窗口外的时候,你怎么判断消息了
这里要用捕获鼠标函数了
SetCapture(hwnd);//捕获到鼠标
ReleaseCapture()//释放鼠标
嗯,我会
 
  
 
  
 
 

你可能感兴趣的:(WINDOWS程序设计 复习(2))