怎么用vcapi函数画矩形,句柄什么意思。详细的代码。实现下面图形。大哥大姐们帮帮忙吧。我头都大了。
1个回答
展开全部
我也是初学者,这个完整界面虽然做出来了但是效果不太好。其实这个是zotin大哥帮我修改过的。
矩形是这样画的:
1.获得设备环境
用GetDC或者BeginPaint
我用BeginPaint做个示范
HDC hdc;
PAINTSTRUCT ps;
hdc = ::BeginPaint(hwnd,&ps);
2.创建画笔 画刷等绘图工具
画笔用来画边框 画刷用来给矩形填充颜色
比如我创建一个天蓝色画刷
HBRUSH hBrush = ::CreateSolidBrush(RGB(0xa6,0xca,0xf0));
3.将绘图工具选入设备环境
这个概念我还没理解,这里我就无法给你示范了
4.调用GDI函数绘图
绘矩形的函数是Rectangle
它的第一个参数就是hdc(在第一步中获得的),第二个参数~第五个参数分别是:要画的矩形距离窗口左边界的距离、距离窗口上边界的距离、距离窗口右边界的距离、距离窗口下边界的距离
你要先定义一个RECT 类型变量,如RECT rt;
这样rt就有四个参数:left、top、right、bottom,分别与Rectangle的第二到第五个参数对应。如:
RECT rt = {200,260,600,310};这样子你调用
::Rectangle(hdc,rt.left,rt.top,rt.right,rt.bottom);就画出一个矩形
给矩形填充颜色用FillRect函数
它的第一个参数也是hdc,第二个参数是指向rt的指针,即: RECT *lpRect = &rt;,第三个参数为你创建的画刷
你调用:FillRect(hdc,lpRect,hBrush);
就可以了
5.恢复设备环境,删除绘图工具
6.释放设备环境
用EndPaint把前边BeginPaint获得的设备环境恢复
::EndPaint(hwnd,&ps);
用::DeleteObject(hBrush);将前边创建的画刷删掉
上面这些操作都是在WM_PAINT消息里进行的。
如果对我的回答有什么疑问可以HI我。
// atm.cpp : 定义应用程序的入口点。
#include "stdafx.h"
#include <string.h>
//窗口客户区的大小
static int s_cxClient;
static int s_cyClient;
//窗口函数的函数原型
LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// 创建窗口的四步:设计窗口类、注册窗口类、创建窗口、注册及更新窗口
const char szClassName[] = "MainWClass";
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW; // 指定如果大小改变就重画
wndclass.lpfnWndProc = MainWndProc; // 窗口函数指针
wndclass.cbClsExtra = 0; // 没有额外的类内存
wndclass.cbWndExtra = 0; // 没有额外的窗口内存
wndclass.hInstance = hInstance; // 实例句柄
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); // 使用预定义图标
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); // 使用预定义的光标
wndclass.hbrBackground = CreateSolidBrush(RGB(0x9B,0x30,0xff)); // 创建画刷 RGB(255,191,192)
wndclass.lpszMenuName = NULL; //不指定菜单
wndclass.lpszClassName = szClassName; //窗口类的名称
//注册这个窗口类
RegisterClass(&wndclass);
//创建主窗口
HWND hwnd = CreateWindow(
"MainWClass",
"api study",
WS_POPUP | WS_SYSMENU | WS_SIZEBOX, // dwStyle,窗口风格 这种风格是去掉菜单栏
CW_USEDEFAULT, // X,初始X坐标
CW_USEDEFAULT, // Y,初始Y坐标
800, // nWidth,宽度
600, // nHeight,高度
NULL, // hWndParent,父窗口句柄
NULL, // hMenu,菜单句柄
hInstance, // hInstance,程序实例句柄
NULL); // lpParam,用户数据
if( NULL == hwnd )
{
MessageBox(NULL,"创建窗口出错!","Error:",MB_OK | MB_ICONHAND);
return -1;
}
//显示窗口,刷新窗口客户区
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
//从消息队列中取出消息,交给窗口函数处理,直到GetMessage返回FALSE,结束消息循环
MSG msg; // 定义消息名
while(GetMessage(&msg,NULL,0,0))
{
//转化键盘消息 即翻译消息
TranslateMessage(&msg);
//将消息发送到相应的窗口函数 即分发消息
DispatchMessage(&msg);
}
//当GetMessage返回FALSE,程序结束
DeleteObject(wndclass.hbrBackground);
return (int)msg.wParam;
}
void DrawAtom( HDC hdc, RECT rt )
{
HBRUSH hBrush = CreateSolidBrush(RGB(0xa6,0xca,0xf0));
HPEN hPen = CreatePen(PS_SOLID,3,RGB(255,191,192)),hOldPen;
// 创建字体
HFONT hFont,hOldFont;
RECT rt1,rt2;
TCHAR szText[] = "欢迎使用很好很强大银行-ATM-机";
TCHAR szAccount[] = "请输入账号:";
TCHAR szPassword[] = "请输入密码:";
TCHAR szAttention[] = "注意:防止您的账号和密码被他人窃取。";
// 画界面轮廓
hOldPen = (HPEN)SelectObject(hdc,hPen);
SetBkMode(hdc,TRANSPARENT); // TRANSPARENT表示字体背景色无作用,即为透明背景;
MoveToEx(hdc,5,5,NULL); // 设置画线出发点坐标为5,5
LineTo(hdc,25,5);
SetTextColor(hdc,RGB(255,191,192));
TextOut(hdc,30,0,"ATM",3);
MoveToEx(hdc,26 + 35,5,NULL);
LineTo(hdc,80,5);
TextOut(hdc,86,0,"很好很强大银行",strlen("很好很强大银行"));
MoveToEx(hdc,193,5,NULL);
LineTo(hdc,s_cxClient - 5,5);
LineTo(hdc,s_cxClient - 5,s_cyClient - 5);
LineTo(hdc,5,s_cyClient - 5);
LineTo(hdc,5,5);
// 创建字体的前两个参数分别是字体的高度和宽度,用s_cxClient和s_cyClient是希望每次重画时字体也可以等比例放缩
hFont = CreateFont(27 * s_cyClient / 600 ,13 * s_cxClient / 800,0,0,FW_HEAVY,0,0,0,ANSI_CHARSET,
OUT_TT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
VARIABLE_PITCH | FF_SWISS,"大道曙光");
// 将字体选入设备
hOldFont = (HFONT)SelectObject(hdc,hFont);
SetTextColor(hdc,RGB(0xf0,0xf0,0xf0)); // 设置字体颜色
TextOut(hdc,rt.right / 4,rt.bottom / 8,szText,strlen(szText)); // 这里用strlen而非sizeof
TextOut(hdc,11,s_cyClient - 27 * s_cyClient / 600 - 5 - 4,szAttention,strlen(szAttention));
rt1.left = rt.right / 4; // 这样处理是想让画出的矩形是按照比例在窗口上分布的
rt1.top = rt.bottom / 3;
rt1.right = rt.right / 4 * 3 ;
rt1.bottom = rt1.top + rt.bottom / 12;
SetTextColor(hdc,RGB(0xD1,0xEE,0xEE));
TextOut(hdc,rt1.left - strlen(szAccount) * 13 * s_cxClient / 800,rt1.top ,szAccount,strlen(szAccount));
Rectangle(hdc,rt1.left,rt1.top,rt1.right,rt1.bottom);
FillRect(hdc,&rt1,hBrush); // 第二个参数是:指向含有将填充矩形的逻辑坐标的RECT结构的指针
rt2.left = rt.right / 4;
rt2.top = rt.bottom / 3 + rt.bottom / 12 + rt.bottom / 30;
rt2.right = rt.right / 4 * 3 ;
rt2.bottom = rt2.top + rt.bottom / 12;
SetTextColor(hdc,RGB(0xD1,0xEE,0xEE));
TextOut(hdc,rt2.left - strlen(szPassword) * 13 * s_cxClient / 800,rt2.top ,szPassword,strlen(szPassword));
Rectangle(hdc,rt2.left,rt2.top,rt2.right,rt2.bottom);
FillRect(hdc,&rt2,hBrush);
SelectObject(hdc, hOldFont);
SelectObject(hdc, hOldPen);
DeleteObject(hBrush);
DeleteObject(hFont);
DeleteObject(hPen);
}
LRESULT CALLBACK MainWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rt;
switch(message)
{
case WM_PAINT: // 窗口客户区需要重画
//使无效的客户区变得有效,并取得设备环境句柄
// 获取设备环境、内存设备环境
hdc = BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rt);
DrawAtom(hdc, rt);
EndPaint(hwnd,&ps);
break;
case WM_SIZE: //每次窗口大小发生变化,系统都会接收到这个消息
{
s_cxClient = LOWORD(lParam);
s_cyClient = HIWORD(lParam);
}
// 使鼠标在客户区也可以拖动窗口
case WM_NCHITTEST:
{
LRESULT nHitTest;
nHitTest = DefWindowProc(hwnd,WM_NCHITTEST,wParam,lParam);
// 如果鼠标左键按下,GetAsyncKeyState函数的返回值小于0
if( nHitTest == HTCLIENT && GetAsyncKeyState(MK_LBUTTON) < 0 )
{
nHitTest = HTCAPTION;
}
return nHitTest;
}
// 右键弹出快捷菜单
case WM_CONTEXTMENU:
{
POINT pt;
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
// 获得系统菜单句柄
HMENU hSysMenu = GetSystemMenu(hwnd,FALSE);
// 弹出系统菜单
int nID = TrackPopupMenu(hSysMenu,TPM_LEFTALIGN | TPM_RETURNCMD,pt.x,pt.y,0,hwnd,NULL);
if( nID > 0 )
{
SendMessage(hwnd,WM_SYSCOMMAND,nID,0);
}
return 0;
}
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
SendMessage(hwnd,WM_CLOSE,0,0);
break;
default:break;
}
break;
case WM_CLOSE:
if(IDOK == MessageBox(hwnd,TEXT("您确定要退出吗?"),TEXT("退出"),MB_ICONQUESTION | MB_OKCANCEL|MB_DEFBUTTON2))
{
DestroyWindow(hwnd);
}
break;
case WM_DESTROY: //正在销毁窗口
//向消息队列投递一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环
PostQuitMessage(0);
break;
default:return DefWindowProc(hwnd,message,wParam,lParam);break; // 将我们不处理的消息交给系统默认处理
}
return 0;
}
关于句柄:
http://tieba.baidu.com/club/6588002/p/7991040
《C语言也能干大事》的作者这样描述句柄,“句柄就是把柄”。我现在也没真正弄明白句柄,不过我想如果对windows程序设计的机制了解之后应该会明白的。
矩形是这样画的:
1.获得设备环境
用GetDC或者BeginPaint
我用BeginPaint做个示范
HDC hdc;
PAINTSTRUCT ps;
hdc = ::BeginPaint(hwnd,&ps);
2.创建画笔 画刷等绘图工具
画笔用来画边框 画刷用来给矩形填充颜色
比如我创建一个天蓝色画刷
HBRUSH hBrush = ::CreateSolidBrush(RGB(0xa6,0xca,0xf0));
3.将绘图工具选入设备环境
这个概念我还没理解,这里我就无法给你示范了
4.调用GDI函数绘图
绘矩形的函数是Rectangle
它的第一个参数就是hdc(在第一步中获得的),第二个参数~第五个参数分别是:要画的矩形距离窗口左边界的距离、距离窗口上边界的距离、距离窗口右边界的距离、距离窗口下边界的距离
你要先定义一个RECT 类型变量,如RECT rt;
这样rt就有四个参数:left、top、right、bottom,分别与Rectangle的第二到第五个参数对应。如:
RECT rt = {200,260,600,310};这样子你调用
::Rectangle(hdc,rt.left,rt.top,rt.right,rt.bottom);就画出一个矩形
给矩形填充颜色用FillRect函数
它的第一个参数也是hdc,第二个参数是指向rt的指针,即: RECT *lpRect = &rt;,第三个参数为你创建的画刷
你调用:FillRect(hdc,lpRect,hBrush);
就可以了
5.恢复设备环境,删除绘图工具
6.释放设备环境
用EndPaint把前边BeginPaint获得的设备环境恢复
::EndPaint(hwnd,&ps);
用::DeleteObject(hBrush);将前边创建的画刷删掉
上面这些操作都是在WM_PAINT消息里进行的。
如果对我的回答有什么疑问可以HI我。
// atm.cpp : 定义应用程序的入口点。
#include "stdafx.h"
#include <string.h>
//窗口客户区的大小
static int s_cxClient;
static int s_cyClient;
//窗口函数的函数原型
LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// 创建窗口的四步:设计窗口类、注册窗口类、创建窗口、注册及更新窗口
const char szClassName[] = "MainWClass";
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW; // 指定如果大小改变就重画
wndclass.lpfnWndProc = MainWndProc; // 窗口函数指针
wndclass.cbClsExtra = 0; // 没有额外的类内存
wndclass.cbWndExtra = 0; // 没有额外的窗口内存
wndclass.hInstance = hInstance; // 实例句柄
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); // 使用预定义图标
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); // 使用预定义的光标
wndclass.hbrBackground = CreateSolidBrush(RGB(0x9B,0x30,0xff)); // 创建画刷 RGB(255,191,192)
wndclass.lpszMenuName = NULL; //不指定菜单
wndclass.lpszClassName = szClassName; //窗口类的名称
//注册这个窗口类
RegisterClass(&wndclass);
//创建主窗口
HWND hwnd = CreateWindow(
"MainWClass",
"api study",
WS_POPUP | WS_SYSMENU | WS_SIZEBOX, // dwStyle,窗口风格 这种风格是去掉菜单栏
CW_USEDEFAULT, // X,初始X坐标
CW_USEDEFAULT, // Y,初始Y坐标
800, // nWidth,宽度
600, // nHeight,高度
NULL, // hWndParent,父窗口句柄
NULL, // hMenu,菜单句柄
hInstance, // hInstance,程序实例句柄
NULL); // lpParam,用户数据
if( NULL == hwnd )
{
MessageBox(NULL,"创建窗口出错!","Error:",MB_OK | MB_ICONHAND);
return -1;
}
//显示窗口,刷新窗口客户区
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
//从消息队列中取出消息,交给窗口函数处理,直到GetMessage返回FALSE,结束消息循环
MSG msg; // 定义消息名
while(GetMessage(&msg,NULL,0,0))
{
//转化键盘消息 即翻译消息
TranslateMessage(&msg);
//将消息发送到相应的窗口函数 即分发消息
DispatchMessage(&msg);
}
//当GetMessage返回FALSE,程序结束
DeleteObject(wndclass.hbrBackground);
return (int)msg.wParam;
}
void DrawAtom( HDC hdc, RECT rt )
{
HBRUSH hBrush = CreateSolidBrush(RGB(0xa6,0xca,0xf0));
HPEN hPen = CreatePen(PS_SOLID,3,RGB(255,191,192)),hOldPen;
// 创建字体
HFONT hFont,hOldFont;
RECT rt1,rt2;
TCHAR szText[] = "欢迎使用很好很强大银行-ATM-机";
TCHAR szAccount[] = "请输入账号:";
TCHAR szPassword[] = "请输入密码:";
TCHAR szAttention[] = "注意:防止您的账号和密码被他人窃取。";
// 画界面轮廓
hOldPen = (HPEN)SelectObject(hdc,hPen);
SetBkMode(hdc,TRANSPARENT); // TRANSPARENT表示字体背景色无作用,即为透明背景;
MoveToEx(hdc,5,5,NULL); // 设置画线出发点坐标为5,5
LineTo(hdc,25,5);
SetTextColor(hdc,RGB(255,191,192));
TextOut(hdc,30,0,"ATM",3);
MoveToEx(hdc,26 + 35,5,NULL);
LineTo(hdc,80,5);
TextOut(hdc,86,0,"很好很强大银行",strlen("很好很强大银行"));
MoveToEx(hdc,193,5,NULL);
LineTo(hdc,s_cxClient - 5,5);
LineTo(hdc,s_cxClient - 5,s_cyClient - 5);
LineTo(hdc,5,s_cyClient - 5);
LineTo(hdc,5,5);
// 创建字体的前两个参数分别是字体的高度和宽度,用s_cxClient和s_cyClient是希望每次重画时字体也可以等比例放缩
hFont = CreateFont(27 * s_cyClient / 600 ,13 * s_cxClient / 800,0,0,FW_HEAVY,0,0,0,ANSI_CHARSET,
OUT_TT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
VARIABLE_PITCH | FF_SWISS,"大道曙光");
// 将字体选入设备
hOldFont = (HFONT)SelectObject(hdc,hFont);
SetTextColor(hdc,RGB(0xf0,0xf0,0xf0)); // 设置字体颜色
TextOut(hdc,rt.right / 4,rt.bottom / 8,szText,strlen(szText)); // 这里用strlen而非sizeof
TextOut(hdc,11,s_cyClient - 27 * s_cyClient / 600 - 5 - 4,szAttention,strlen(szAttention));
rt1.left = rt.right / 4; // 这样处理是想让画出的矩形是按照比例在窗口上分布的
rt1.top = rt.bottom / 3;
rt1.right = rt.right / 4 * 3 ;
rt1.bottom = rt1.top + rt.bottom / 12;
SetTextColor(hdc,RGB(0xD1,0xEE,0xEE));
TextOut(hdc,rt1.left - strlen(szAccount) * 13 * s_cxClient / 800,rt1.top ,szAccount,strlen(szAccount));
Rectangle(hdc,rt1.left,rt1.top,rt1.right,rt1.bottom);
FillRect(hdc,&rt1,hBrush); // 第二个参数是:指向含有将填充矩形的逻辑坐标的RECT结构的指针
rt2.left = rt.right / 4;
rt2.top = rt.bottom / 3 + rt.bottom / 12 + rt.bottom / 30;
rt2.right = rt.right / 4 * 3 ;
rt2.bottom = rt2.top + rt.bottom / 12;
SetTextColor(hdc,RGB(0xD1,0xEE,0xEE));
TextOut(hdc,rt2.left - strlen(szPassword) * 13 * s_cxClient / 800,rt2.top ,szPassword,strlen(szPassword));
Rectangle(hdc,rt2.left,rt2.top,rt2.right,rt2.bottom);
FillRect(hdc,&rt2,hBrush);
SelectObject(hdc, hOldFont);
SelectObject(hdc, hOldPen);
DeleteObject(hBrush);
DeleteObject(hFont);
DeleteObject(hPen);
}
LRESULT CALLBACK MainWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rt;
switch(message)
{
case WM_PAINT: // 窗口客户区需要重画
//使无效的客户区变得有效,并取得设备环境句柄
// 获取设备环境、内存设备环境
hdc = BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rt);
DrawAtom(hdc, rt);
EndPaint(hwnd,&ps);
break;
case WM_SIZE: //每次窗口大小发生变化,系统都会接收到这个消息
{
s_cxClient = LOWORD(lParam);
s_cyClient = HIWORD(lParam);
}
// 使鼠标在客户区也可以拖动窗口
case WM_NCHITTEST:
{
LRESULT nHitTest;
nHitTest = DefWindowProc(hwnd,WM_NCHITTEST,wParam,lParam);
// 如果鼠标左键按下,GetAsyncKeyState函数的返回值小于0
if( nHitTest == HTCLIENT && GetAsyncKeyState(MK_LBUTTON) < 0 )
{
nHitTest = HTCAPTION;
}
return nHitTest;
}
// 右键弹出快捷菜单
case WM_CONTEXTMENU:
{
POINT pt;
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
// 获得系统菜单句柄
HMENU hSysMenu = GetSystemMenu(hwnd,FALSE);
// 弹出系统菜单
int nID = TrackPopupMenu(hSysMenu,TPM_LEFTALIGN | TPM_RETURNCMD,pt.x,pt.y,0,hwnd,NULL);
if( nID > 0 )
{
SendMessage(hwnd,WM_SYSCOMMAND,nID,0);
}
return 0;
}
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
SendMessage(hwnd,WM_CLOSE,0,0);
break;
default:break;
}
break;
case WM_CLOSE:
if(IDOK == MessageBox(hwnd,TEXT("您确定要退出吗?"),TEXT("退出"),MB_ICONQUESTION | MB_OKCANCEL|MB_DEFBUTTON2))
{
DestroyWindow(hwnd);
}
break;
case WM_DESTROY: //正在销毁窗口
//向消息队列投递一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环
PostQuitMessage(0);
break;
default:return DefWindowProc(hwnd,message,wParam,lParam);break; // 将我们不处理的消息交给系统默认处理
}
return 0;
}
关于句柄:
http://tieba.baidu.com/club/6588002/p/7991040
《C语言也能干大事》的作者这样描述句柄,“句柄就是把柄”。我现在也没真正弄明白句柄,不过我想如果对windows程序设计的机制了解之后应该会明白的。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询