windows程序设计之GDI简介

最近在做一个有关激光笔的小项目,和学长们一起做的。里面还有硬件成份,现在因为才开始做,我主要做软件上面的东西,当然技术含量是很少的抓狂···诶,学了一年左右了,水平还是没很大长进啊~~~大哭刚刚C入门,SDK也只能说勉强算是入门了吧。。。项目里面有一部分是要绘制出来鼠标的移动轨迹的,我就去重新看了下GDI,发现自己以前没写过这些东西,印象就是不深刻啊,于是就温习了下。重新看了下<<windows程序设计>>和<<API函数,接口编程实例>>,ctrl+c和ctrl+v出来下面个实验品,然后做了些笔记,我还是记得学长讲得那句话:博客就是用来记录自己成长的地方。无论有什么学到的,都可以写上来,无论含量高不高,总能在自己以后有一天需要的时候想起来,并且找到,这大概和老师说的好记性不如让笔头差不多吧~~~

下面是自己一些简单的总结:

windows GDI绘图
Graphics Device Interface:图形设备接口
GDI是GraphicsDeviceInterface的缩写,含义是图形设备接口,它的主要任务是负责系统与绘图程序之间的信息交换,处理所有Windows程序的图形输出。
在Windows操作系统下,绝大多数具备图形界面的应用程序都离不开GDI,我们利用GDI所提供的众多函数就可以方便的在屏幕、打印机及其它输出设备上输出图形,文本等操作。GDI的出现使程序员无需要关心硬件设备及设备驱动,就可以将应用程序的输出转化为硬件设备上的输出,实现了程序开发者与硬件设备的隔离,大大方便了开发工作。

1.资源使用
// 初始的颜色
BYTE bRed = 0;
BYTE bGreen = 0;
BYTE bBlue = 0;
// 笔的颜色 正黑
COLORREF cPen = RGB(bRed, bGreen, bBlue);
//画笔的设置
HPEN CreatePen(
__in int fnPenStyle,
__in int nWidth,
__in COLORREF crColor
);
HPEN hpen;
hpen = CreatePen(PS_SOLID, 10, cPen);//画笔基本属性

//画刷的设置
HBRUSH hbrush;
COLORREF cBrush = RGB(233, GetGValue(cPen),255);
hbrush = CreateSolidBrush(cBrush);
// 释放资源
DeleteObject(hpen);
DeleteObject(hbrush);


2.获取DC。获取了DC就相当于获取了绘画的资格。
HDC hDC = GetDC(hWnd);//参数是NULL时获取的是整个显示器的DC,若是句柄就是指定窗口的DC。


3.将DC设置成对象目标句柄。将图形对象选入DC中,这样DC中原有的类型图形对象就会被新的对象替换。
SelectObject(hDC, hpen);
SelectObject(hDC, hbrush);
这样绘画的时候就可以改变默认的DC属性。


4.绘画区域的变化
GetClientRect(hWnd, &rect);这里获取的是客户区域的大小,是以客户区左上角为坐标原点进行创建的。因此比如在处理WM_MOUSEMOVE等鼠标消息的时候,传进来的lParam参数中包含的坐标也是相对于客户端的。要想转化成屏幕坐标可以用下面的方法:
//转换窗口有效区为屏幕座标
POINT point;
point.x = 0, point.y = 0;
ClientToScreen(hWnd,&point);
你要是想把光标限制在客户区内,可以这样:
//将光标限定在窗口有效区内
rect.top = point.y;
rect.left = point.x;
rect.bottom += rect.top;
rect.right += rect.left;
ClipCursor(&rect); //rect一定要是屏幕座标
下面是获取屏幕坐标的函数
POINT pt;
GetCursorPos(&pt);
这里获取的坐标就是相对屏幕左上角的坐标。若是要转化成客户区坐标可以用
ScreenToClient(hWnd,&point);


5.绘制线条
移到指定的点

BOOL MoveToEx( __in HDC hdc, __in int X, __in int Y, __out LPPOINT lpPoint //Pointer to a POINT structure that receives the previous current position. If this parameter is a //NULL pointer, the previous position is not returned. ); //画直线 BOOL LineTo( __in HDC hdc, __in int nXEnd, __in int nYEnd ); // 绘制矩形 BOOL Rectangle( __in HDC hdc, __in int nLeftRect, __in int nTopRect, __in int nRightRect, __in int nBottomRect ); //绘制椭圆(圆) BOOL Ellipse( __in HDC hdc, __in int nLeftRect, __in int nTopRect, __in int nRightRect, __in int nBottomRect ); //绘制矩形 BOOL Rectangle( __in HDC hdc, __in int nLeftRect, __in int nTopRect, __in int nRightRect, __in int nBottomRect ); //绘制圆角矩形 BOOL RoundRect( __in HDC hdc, __in int nLeftRect, __in int nTopRect, __in int nRightRect, __in int nBottomRect, __in int nWidth, __in int nHeight );


下面是我修改的一个绘制鼠标轨迹的小程序

#include <windows.h> #include <stdio.h> #define MAXGUIDESEGMENTS 1000 #define MyAlloc(dwSize) HeapAlloc(GetProcessHeap(),0,dwSize) #define MyFree(lpMem) HeapFree(GetProcessHeap(),0,lpMem); LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; BOOL GetGuideLine(HWND hWnd, LPPOINT *lpPoint, LPDWORD lpdwNumPts); LONG clsCur; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("LineDemo") ; 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 ("Program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, TEXT ("Line Demonstration"), 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 ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hDC = NULL ; static LPPOINT lpRed = NULL; static DWORD dwRed = 0; switch (message) { case WM_CREATE: hDC = GetDC(hwnd); break; case WM_LBUTTONDOWN: //取得窗口有效区 RECT rect; GetClientRect(hwnd,&rect); //转换窗口有效区为屏幕座标 POINT point; point.x = 0, point.y = 0; ClientToScreen(hwnd,&point); rect.top = point.y; rect.left = point.x; rect.bottom += rect.top; rect.right += rect.left; ClipCursor(&rect); //rect一定要是屏幕座标 if (!clsCur) { clsCur = GetClassLong(hwnd,GCL_HCURSOR); //取当前窗口的光标 } SetClassLong(hwnd,GCL_HCURSOR,NULL); //设置当前窗口的光标为NULL SetCursor(LoadCursor(NULL, IDC_CROSS)); //设置当前光标为十字形 GetGuideLine(hwnd, &lpRed, &dwRed); break; case WM_DESTROY: if (lpRed) MyFree(lpRed); PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } BOOL GetGuideLine(HWND hWnd, LPPOINT *lpPoint, LPDWORD lpdwNumPts) { MSG msg; HDC hDC = GetDC(hWnd); BOOL bFirstTime = TRUE; DWORD dwPos = 0; RECT rect; static HPEN hpen; hpen = CreatePen(PS_SOLID,3, RGB(0,255,0)); SelectObject(hDC,hpen); GetClientRect(hWnd, &rect); // 为点数组分配空间 *lpPoint = (LPPOINT)MyAlloc(MAXGUIDESEGMENTS * sizeof(POINT)); SetCapture(hWnd); // 设置鼠标捕获器 // 将客户区填充为白色 GetClientRect(hWnd, &rect); PatBlt(hDC, 0, 0, rect.right, rect.bottom, WHITENESS); while(1) { // 过滤所有鼠标消息 WaitMessage(); if (PeekMessage(&msg,NULL,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE)) { // 判断是否在客户区中 if ((LOWORD(msg.lParam) < rect.right) && (HIWORD(msg.lParam) < rect.bottom)) { // 是否第一次收到消息 if (bFirstTime) { bFirstTime = FALSE; // 如果是第一次将笔的起点移动到鼠标点击的位置 MoveToEx(hDC, LOWORD(msg.lParam), HIWORD(msg.lParam), NULL); } // 是否达到了最大点数 if (dwPos < MAXGUIDESEGMENTS) { // 鼠标的移动会产生鼠标消息,每收到一次消息保存一个点 (*lpPoint)[dwPos].x = LOWORD(msg.lParam); (*lpPoint)[dwPos].y = HIWORD(msg.lParam); // 绘制到鼠标所在的点 LineTo(hDC, (*lpPoint)[dwPos].x, (*lpPoint) [dwPos].y); dwPos++; } } } if (msg.message == WM_RBUTTONDOWN) { ClipCursor(NULL); SetClassLong(hWnd,GCL_HCURSOR, clsCur); SetCursor((HCURSOR)clsCur); break; } else continue; } *lpdwNumPts = dwPos; ReleaseDC(hWnd, hDC); ReleaseCapture(); DeleteDC( hDC ); return TRUE; }


最近的时间越来越紧啊···专业课越来越难,自己课余学计算机的时间也越来越少,诶····真是后后悔自己没去计算机专业额····

呼呼,,,,不过事在人为,努力就好!昨天看到一句比较好的话:一个优秀的程序员:勤奋+执着!我看着很有感触,有时

时觉得自己花那么多时间面对代码,是否值得···不过我想有付出就会有回报的!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值