面向对象编程技术
实验四实验报告
目录
2.2.1 增加对WM_PAINT消息的处理,在窗口客户区输出文本
2.3.1 自定义MyPolyline函数替代Polyline库函数
2.3.2 自定义MyPolyPolyline函数替代PolyPolyline函数
创建MyDlg工程用于完成本次实验要求的第一部分——对话框相关内容。在创建Windows桌面应用程序后,完成下列步骤:
- 按照“属性——>配置属性——>高级——>字符集——>未设置”的步修改字符集
- 将解决方案平台修改为X86
- “属性——>链接器——>系统——>子系统——>窗口进行修改
- 完成上面三步后,复制Windows 应用程序基本框架的内容进来,进行修改
图 1 MyDlg工程
创建MyDlg工程用于完成本次实验要求的第二部分——图形绘制函数的使用。在创建Windows桌面应用程序后,完成下列步骤:
- 按照“属性——>配置属性——>高级——>字符集——>未设置”的步修改字符集
- 将解决方案平台修改为X86
- “属性——>链接器——>系统——>子系统——>窗口进行修改
- 完成上面三步后,复制Windows 应用程序基本框架的内容进来,进行修改
图 2 MyGDI工程
在WM_PAINT消息里用BeginPaint()函数得到设备句柄hdc,然后使用SetTextColor()函数设置要输出的文本的颜色,最后采用TextOut()函数输出文本。
/*
*在窗口客户区输出文本
*/
case WM_PAINT: //客户区重绘消息
hdc = BeginPaint(hWnd, &ps);
SetTextColor(hdc, RGB(0, 255, 0));
TextOut(hdc, 300, 100, TEXT("面向对象编程实验四"), LENGTH);
EndPaint(hWnd, &ps);
return 0;
图 3 文本输出结果
增加菜单资源总体分为三步,如图 3
- ID。
图 5 新建菜单资源
图 6 包含菜单
(为了避免冗余,暂时只处理两个菜单命令的快捷键),如图 6
- 消息循环前装载加速键表
/*
*装载加速键表
*/
HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MYDLG_Accelerator));
使用LoadAccelerators()函数,第一个参数为当前程序实例句柄,第二个参数为快捷键资源ID。
- 修改消息循环
/*
*修改后的消息循环
*/
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(ghWnd, hAccel, &msg))//不是加速键
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
由图 7可以看出,此时并未点击上方菜单栏,仅仅CTRL+M就新建了文件(举例子,仅仅调用了MessageBox函数)。
快捷菜单又叫做上下文菜单,一般是为了方便用户而设置,用户点击鼠标右键就会弹出。设置快捷菜单分为两步。
- 在主窗口消息处理函数里装载快捷菜单
/*
*装载快捷菜单
*/
HMENU hPopMenu = LoadMenu((HINSTANCE)GetWindowLong(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDR_MyDlg_MENU));
hPopMenu = GetSubMenu(hPopMenu, 0);
使用LoadAccelerators()函数,第一个参数为当前程序实例句柄,第二个参数为菜单资源ID,并选中第一列菜单作为上下文菜单。
- 在鼠标消息里进一步设置
/*
*处理鼠标右键单击消息
*/
POINT pt;
case WM_RBUTTONUP:
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
ClientToScreen(hWnd, &pt);
TrackPopupMenu(hPopMenu, TPM_VCENTERALIGN, pt.x, pt.y, 0, hWnd, NULL);
break;
图 9 快捷菜单响应
自定义对话框的步骤如
图 10 自定义对话框流程图
- 首先建立想要的对话框模式图,为了方便后面的使用,注意修改ID
图 11 对话框模板
- 接着编写对话框消息处理函数,记得在前面声明函数头。
/*
*对话框消息处理函数
*/
BOOL CALLBACK DlgTextProc(HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam)
{
hDlg1 = hDlg;
switch (message)
{
case WM_INITDIALOG:
return 0;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
gColorText = crText;
InvalidateRect(ghWnd, NULL, FALSE);
EndDialog(hDlg, 1);
break;
case IDCANCEL:
EndDialog(hDlg, 1);
break;
case IDC_BUTTON:
if (GetMyColor(hDlg, &crText))
{
SetDlgItemInt(hDlg, IDC_STATIC_1, GetRValue(crText), FALSE);
SetDlgItemInt(hDlg, IDC_STATIC_2, GetGValue(crText), FALSE);
SetDlgItemInt(hDlg, IDC_STATIC_3, GetBValue(crText), FALSE);
}
break;
}
break;
}
return FALSE;
}
使用SetDlgItemInt()函数与GetValue()函数分别取出RGB值,将其显示在static里
- 激活对话框
/*
*菜单命令,激活对话框
*/
switch (LOWORD(wParam))
{
case ID_XINJIAN:
MessageBox(hWnd, TEXT("新建成功"), TEXT("新建"), MB_OK | MB_ICONINFORMATION);
break;
case ID_TEXTCOLOR:
DialogBox((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
MAKEINTRESOURCE(IDD_MyDlg_DLG),
hWnd,
DlgTextProc);
break;
}
- 最后将菜单命令与对话框命令结合起来,验证功能的实现。
图 12 初始状态
图 13 点击“更改文本颜色”
图 14 点击“选择颜色”
图 15 选择红色
图 16 自动显示RGB(255, 0, 0)
图 17 文本被设置为红色
(1)Polyline()函数
通过连接指定数组中的点来绘制一系列线段。
/*
*Polyline()函数绘图
*/
POINT pts[] = { {50,50},{400,100},{150,360} };
case WM_PAINT: //客户区重绘消息
hdc = BeginPaint(hWnd, &ps);
Polyline(hdc, pts, 3);
EndPaint(hWnd, &ps);
return 0;
图 18 Polyline()函数绘图
(2)PolylineTo()函数绘图
PolylineTo()函数与Polyline()函数类似,细微的差距在于前者默认从客户区左上角开始。
/*
*PolylineTo()函数绘图
*/
case WM_PAINT: //客户区重绘消息
hdc = BeginPaint(hWnd, &ps);
PolylineTo(hdc, pts, 3);
EndPaint(hWnd, &ps);
return 0;
图 19 PolylineTo()函数绘图
(3)Polygon()函数绘图
绘制由直线连接的两个或多个顶点组成的多边形
/*
*Polygon()函数绘图
*/
case WM_PAINT: //客户区重绘消息
hdc = BeginPaint(hWnd, &ps);
Polygon(hdc, pts,3);
EndPaint(hWnd, &ps);
return 0;
图 20 Polygon()函数绘图
(1)绘制矩形
绘制矩形使用Rectangle()函数,参数为窗口句柄与左上角、右下角两个点坐标。
/*
*绘制矩形
*/
RECT rect;
rect.left = 50;
rect.right = 200;
rect.top = 100;
rect.bottom = 200;
case WM_PAINT: //客户区重绘消息
hdc = BeginPaint(hWnd, &ps);
Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
//MyPolyline(hdc, pts,3);
EndPaint(hWnd, &ps);
return 0;
图 21 绘制矩形
(2)绘制椭圆形
绘制椭圆使用Ellipse()函数,参数与Rectangle相同
/*
*绘制椭圆
*/
Ellipse(hdc, rect.left, rect.top, rect.right, rect.bottom);
图 22 绘制椭圆
/*
*使用画笔和画刷绘制并填充椭圆形
*/
case WM_PAINT: //客户区重绘消息
hdc = BeginPaint(hWnd, &ps);
hPen = CreatePen(PS_DASH, 1, RGB(255, 0, 0));
nOldPen = SelectObject(hdc, hPen);
hBrush = CreateSolidBrush(RGB(0, 255, 0));
nOldBrush = SelectObject(hdc, hBrush);
Ellipse(hdc, rect.left, rect.top, rect.right, rect.bottom);
//Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
//MyPolyline(hdc, pts,3);
SelectObject(hdc, nOldPen);
DeleteObject(hPen);
SelectObject(hdc, nOldPen);
DeleteObject(hPen);
EndPaint(hWnd, &ps);
return 0;
图 23 使用画笔和画刷绘制并填充椭圆形
- 用SYSTEMTIME结构定义一个时间结构变量
- 用GetSystemTime函数或GetLocalTime函数取出系统时间或本地时间
- 将时间值打印成字符串(可以使用wsprintf函数或sprintf函数)
- 使用GetDC函数获取HDC
- 用TextOut 或 DrawText函数输出文本
- 用ReleaseDC函数释放先前获取的HDC
- 在WM_DESTROY消息中增加删除已创建的定时器的代码
/*
*定时器的使用
*/
case WM_CREATE: //创建消息
SetTimer(hWnd, TIME_ID, 500, NULL);
return 0;
case WM_TIMER:
SYSTEMTIME time;
GetLocalTime(&time);
wsprintf(showTime, "当前的时间为:%d年%d月%d日%d时%d分%d秒",
time.wYear,
time.wMonth,
time.wDay,
time.wHour,
time.wMinute,
time.wSecond);
hdc = GetDC(hWnd);
TextOut(hdc, 400, 50, showTime, strlen(showTime));
ReleaseDC;
break;
图 24 定时器消息的处理
/*
*自定义MyPolyline函数
*/
BOOL MyPolyline(HDC hdc, POINT* pts, int cpt)
{
int flag = FALSE;
for (int i = 0; i < cpt; )
{
MoveToEx(hdc, pts[i].x, pts[i].y, NULL);
i++;
LineTo(hdc, pts[i].x, pts[i].y);
if (i == cpt)
flag = TRUE;
}
return flag;
}
运行结果与Polyline库函数的运行结果一致。
/*
*自定义MyPolyPolyline函数
*/
BOOL MyPolyPolyline(HDC hdc, POINT* apt, DWORD* asz, DWORD csz)
{
int number = 0;
int i;
int flag = 0;//标志,当函数成功运行时返回1,否则返回0
for ( i = 0; i < csz; i++)
{
int j;
MoveToEx(hdc, apt[number].x, apt[number].y, NULL);
for (j = 1; j < asz[i]; j++)
{
LineTo(hdc, apt[number + j].x, apt[number + j].y);
}
number += j;
}
if (i == csz)
flag = 1;
return flag;
}
/*
*自定义MyPolyPolygon函数
*/
(1)模式对话框 - 当对话框显示时,会禁止其他窗口的输入等用户交互操作。
(2)非模式对话框 - 在对话框显示后,其他窗口同样可以接收输入等用户交互操作。
BOOL CALLBACK DialogProc(
HWND hwndDlg, //窗口句柄
UINT uMsg, //消息ID
WPARAM wParam, //消息参数
LPARAM lParam //消息参数
);
返回TRUE表示DialogProc函数中处理了这个消息,缺省处理函数不需要处理。
返回FALSE表示DialogProc函数未处理这个消息,交给缺省处理函数处理。
一个颜色的值可以用COLORREF表示,使用宏RGB可以给COLORREF赋值,并且可以通过GetRValue/GetGValue/GetBValue这三个函数来获取宏RGB中的每个值。
GetPixel函数可以获取指定点点颜色
SetPixel函数可以设置点的颜色,该函数的返回值为以前的颜色。
- 线的使用
MoveToEx函数,移动到指定点
LineTo函数从当前点到指定点绘制一条直线。
- 封闭图形的绘制函数
Rectangle绘制矩形
Ellipse绘制圆形
RoundRect绘制圆角矩形
Arc绘制弧线
1)创建画笔 - CreatePen
2)将画笔应用到DC中 - SelectObject,该函数返回原来的GDI绘图对象的句柄,需要保存起来,绘图结束后需要在将原来的GDI对象在重新选入替代自己创建的画笔
3)绘图
4)取出DC中的画笔,将原来的画笔,使用SelectObject函数放入设备DC中,就会将我们创建的画笔取出。
5)释放画笔 - DeleteObject
- 画刷的使用
1)创建画刷
CreateSolidBrush - 创建实心画刷
CreateHatchBrush - 创建阴影画刷
CreatePatternBrush - 创建位图画刷
2)将画刷应用到DC中 - SelectObject
3)绘图
4)将画刷从DC中取出 - SelectObject
5)删除画刷 - DeleteObject
-
- 定时器
- 定时器消息
- 定时器
可以在程序中设置定时器,当到达时间间隔时,定时器会向窗口发送一个WM_TIMER消息,定时器的精度为毫秒,但是精准度很低。
消息的参数
WPARAM - 定时器ID
LPARAM - 定时器处理函数的指针
-
-
- 定时器的使用步骤
-
创建定时器
UINT SetTimer(
HWND hWnd, //定时器窗口句柄
UINT nIDEvent, //定时器ID
UINT uElapse, //时间间隔
TIMERPROC lpTimerFunc //定时器处理函数指针
);创建成功,返回非0.
说明:当lpTimerFunc设置为NULL时,使用窗口处理函数作为定时器处理函数,否则就使用定时器处理函数处理定时器消息
消息处理 WM_TIMER
关闭定时器
BOOL KillTimer(
HWND hWnd, //定时器窗口句柄
UINT uIDEvent //定时器ID
);
- 附录 关键代码
/*******************************************************************
程序:MyDlg
文件:MyDlg.cpp
功能:对话框处理
********************************************************************/
#include <windows.h>
#include <windowsx.h>
#include "resource.h"
#define LENGTH 18
COLORREF gColorText;
COLORREF crText;
HWND hDlg1;
HWND ghWnd;
//函数声明
BOOL InitWindow(HINSTANCE a, int b);//这个也是自定义函数
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK DlgTextProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
BOOL GetMyColor(HWND hWnd, LPCOLORREF lpColor);
/*******************************************************************
函数:WinMain ()
功能:Win32 应用程序入口函数。创建主窗口,处理消息循环
********************************************************************/
int WINAPI WinMain(HINSTANCE hInstance, //当前实例句柄
HINSTANCE hPrevInstance, //前一个实例句柄
PSTR szCmdLine, //命令行字符
int iCmdShow) //窗口显示方式
{
MSG msg;
//创建主窗口
if (!InitWindow(hInstance, iCmdShow))
return FALSE;
//进入消息循环:从该应用程序的消息队列中检取消息,
//送到消息处理过程,当检取到WM_QUIT消息时,退出消息循环。
HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MYDLG_Accelerator));//拿到加速键表句柄
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(ghWnd, hAccel, &msg))//不是加速键
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
/******************************************************************
函数:InitWindow ()
功能:创建窗口。
*******************************************************************/
static BOOL InitWindow(HINSTANCE hInstance, int iCmdShow)
{
static CHAR szAppName[] = TEXT("Dlg"); //应用程序名称
HWND hwnd; //窗口句柄
WNDCLASS wcMainWnd; //窗口类结构
ATOM a;
//填充窗口类结构
wcMainWnd.style = CS_VREDRAW | CS_HREDRAW;
wcMainWnd.lpfnWndProc = WinProc;
wcMainWnd.cbClsExtra = 0;
wcMainWnd.cbWndExtra = 0;
wcMainWnd.hInstance = hInstance;
wcMainWnd.hIcon = NULL;// LoadIcon(hInstance, IDI_APPLICATION);
wcMainWnd.hCursor = NULL;// LoadCursor(NULL, IDC_ARROW);
wcMainWnd.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wcMainWnd.lpszMenuName = MAKEINTRESOURCE(IDR_MyDlg_MENU);
wcMainWnd.lpszClassName = szAppName;
//注册窗口类
a = RegisterClass(&wcMainWnd);
if (!a)
{
MessageBox(NULL, TEXT("注册窗口类失败!"), szAppName,
MB_ICONERROR);
return 0;
}
//创建主窗口
hwnd = CreateWindow(szAppName, //窗口类名称
TEXT("实验四"), //窗口标题
WS_OVERLAPPEDWINDOW, //窗口风格
250, //窗口位置的x坐标
100, //窗口位置的y坐标
800, //窗口的宽度
500, //窗口的高度
NULL, //父窗口句柄
NULL, //菜单句柄
hInstance, //应用程序实例句柄
NULL); //窗口创建数据指针
if (!hwnd) return FALSE;
//显示并更新窗口
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
return TRUE;
}
/******************************************************************
函数:WinProc ()
功能:处理主窗口消息
*******************************************************************/
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
ghWnd = hWnd;
HDC hdc;
PAINTSTRUCT ps;
HPEN hPen;
HGDIOBJ nOldPen;
CHAR szShow[40];
POINT pt;
RECT rect;
HMENU hPopMenu = LoadMenu((HINSTANCE)GetWindowLong(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDR_MyDlg_MENU));
hPopMenu = GetSubMenu(hPopMenu, 0);
switch (message)
{
case WM_RBUTTONUP:
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
ClientToScreen(hWnd, &pt);
TrackPopupMenu(hPopMenu, TPM_VCENTERALIGN, pt.x, pt.y, 0, hWnd, NULL);
break;
case WM_COMMAND:
if (lParam) // 控件通知消息
{
if (LOWORD(wParam) == 1) // 编辑控件通知消息
{
if ((HIWORD(wParam) == EN_ERRSPACE || HIWORD(wParam) == EN_MAXTEXT))
MessageBox(hWnd, TEXT("编辑控件内存溢出"),
TEXT("菜单示例程序"), MB_OK | MB_ICONSTOP);
}
else {
if (HIWORD(wParam) == BN_CLICKED)
{
}
}
}
else
{
// 菜单命令
switch (LOWORD(wParam))
{
case ID_XINJIAN:
MessageBox(hWnd, TEXT("新建成功"), TEXT("新建"), MB_OK | MB_ICONINFORMATION);
break;
case ID_TEXTCOLOR:
DialogBox((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
MAKEINTRESOURCE(IDD_MyDlg_DLG),
hWnd,
DlgTextProc);
break;
}
}
return 0;
case WM_MOUSEMOVE:
wsprintf(szShow, "鼠标位置: %04d,%04d", GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
hdc = GetDC(hWnd);
TextOut(hdc, 58, 18, szShow, strlen(szShow));
ReleaseDC(hWnd, hdc);
return 0;
case WM_CREATE: //创建消息
return 0;
case WM_KEYDOWN: //击键消息
switch (wParam)
{
case VK_ESCAPE:
MessageBox(hWnd, TEXT("ESC键按下了!"), TEXT("键盘"), MB_OK);
break;
}
return 0;
case WM_PAINT: //客户区重绘消息
hdc = BeginPaint(hWnd, &ps);
SetTextColor(hdc, gColorText);
TextOut(hdc, 300, 100, TEXT("面向对象编程实验四"), LENGTH);
/*hPen = CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
nOldPen = SelectObject(hdc, hPen);
SelectObject(hdc, nOldPen);
DeleteObject(hPen);*/
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
//调用缺省消息处理过程
return DefWindowProc(hWnd, message, wParam, lParam);
} //函数 WinProc 结束
BOOL CALLBACK DlgTextProc(HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam)
{
hDlg1 = hDlg;
switch (message)
{
case WM_INITDIALOG:
return 0;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
gColorText = crText;
InvalidateRect(ghWnd, NULL, FALSE);
EndDialog(hDlg, 1);
break;
case IDCANCEL:
EndDialog(hDlg, 1);
break;
case IDC_BUTTON:
if (GetMyColor(hDlg, &crText))
{
SetDlgItemInt(hDlg, IDC_STATIC_1, GetRValue(crText), FALSE);
SetDlgItemInt(hDlg, IDC_STATIC_2, GetGValue(crText), FALSE);
SetDlgItemInt(hDlg, IDC_STATIC_3, GetBValue(crText), FALSE);
}
break;
}
break;
}
return FALSE;
}
BOOL GetMyColor(HWND hWnd, LPCOLORREF lpColor)
{
BOOL bRet = FALSE;
COLORREF colors[16];
CHOOSECOLOR cc;
memset(&cc, 0, sizeof(CHOOSECOLOR));
cc.lStructSize = sizeof(CHOOSECOLOR);
cc.hwndOwner = hWnd;
cc.rgbResult = *lpColor;
cc.lpCustColors = colors;
cc.Flags = CC_RGBINIT | CC_FULLOPEN;
if (ChooseColor(&cc))
{
*lpColor = cc.rgbResult;
bRet = TRUE;
}
return bRet;
}
/*******************************************************************
程序:MyGDI
文件:MyGDI.cpp
功能:图形绘制
********************************************************************/
#include <windows.h>
#include <windowsx.h>
#define TIME_ID 1
//函数声明
BOOL InitWindow(HINSTANCE a, int b);//这个也是自定义函数
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
BOOL MyPolyline(HDC hdc, POINT* pts, int cpt);
BOOL MyPolyPolyline(HDC hdc, POINT* apt, DWORD* asz, DWORD csz);
/*******************************************************************
函数:WinMain ()
功能:Win32 应用程序入口函数。创建主窗口,处理消息循环
********************************************************************/
int WINAPI WinMain(HINSTANCE hInstance, //当前实例句柄
HINSTANCE hPrevInstance, //前一个实例句柄
PSTR szCmdLine, //命令行字符
int iCmdShow) //窗口显示方式
{
MSG msg;
//创建主窗口
if (!InitWindow(hInstance, iCmdShow))
return FALSE;
//进入消息循环:从该应用程序的消息队列中检取消息,
//送到消息处理过程,当检取到WM_QUIT消息时,退出消息循环。
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
/******************************************************************
函数:InitWindow ()
功能:创建窗口。
*******************************************************************/
static BOOL InitWindow(HINSTANCE hInstance, int iCmdShow)
{
static CHAR szAppName[] = TEXT("EasyWin"); //应用程序名称
HWND hwnd; //窗口句柄
WNDCLASS wcMainWnd; //窗口类结构
ATOM a;
//填充窗口类结构
wcMainWnd.style = CS_VREDRAW | CS_HREDRAW;
wcMainWnd.lpfnWndProc = WinProc;
wcMainWnd.cbClsExtra = 0;
wcMainWnd.cbWndExtra = 0;
wcMainWnd.hInstance = hInstance;
wcMainWnd.hIcon = NULL;// LoadIcon(hInstance, IDI_APPLICATION);
wcMainWnd.hCursor = NULL;// LoadCursor(NULL, IDC_ARROW);
wcMainWnd.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wcMainWnd.lpszMenuName = NULL;
wcMainWnd.lpszClassName = szAppName;
//注册窗口类
a = RegisterClass(&wcMainWnd);
if (!a)
{
MessageBox(NULL, TEXT("注册窗口类失败!"), szAppName,
MB_ICONERROR);
return 0;
}
//创建主窗口
hwnd = CreateWindow(szAppName, //窗口类名称
TEXT("实验四"), //窗口标题
WS_OVERLAPPEDWINDOW, //窗口风格
250, //窗口位置的x坐标
100, //窗口位置的y坐标
800, //窗口的宽度
500, //窗口的高度
NULL, //父窗口句柄
NULL, //菜单句柄
hInstance, //应用程序实例句柄
NULL); //窗口创建数据指针
if (!hwnd) return FALSE;
//显示并更新窗口
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
return TRUE;
}
/******************************************************************
函数:WinProc ()
功能:处理主窗口消息
*******************************************************************/
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
CHAR szShow[40];
PAINTSTRUCT ps;
RECT rect;
rect.left = 20;
rect.right = 300;
rect.top = 50;
rect.bottom = 500;
HDC hdc;
POINT pts[] = { {50,50},{400,100},{150,360} };
HPEN hPen;
HGDIOBJ nOldPen;
HBRUSH hBrush;
HGDIOBJ nOldBrush;
CHAR showTime[100];
switch (message)
{
case WM_CREATE: //创建消息
SetTimer(hWnd, TIME_ID, 500, NULL);
return 0;
case WM_TIMER:
SYSTEMTIME time;
GetLocalTime(&time);
wsprintf(showTime, "当前的时间为:%d年%d月%d日%d时%d分%d秒",
time.wYear,
time.wMonth,
time.wDay,
time.wHour,
time.wMinute,
time.wSecond);
hdc = GetDC(hWnd);
TextOut(hdc, 400, 50, showTime, strlen(showTime));
ReleaseDC;
break;
case WM_KEYDOWN: //击键消息
switch (wParam)
{
case VK_ESCAPE:
MessageBox(hWnd, TEXT("ESC键按下了!"), TEXT("键盘"), MB_OK);
break;
}
return 0;
case WM_RBUTTONDOWN: //鼠标消息
MessageBox(hWnd, TEXT("鼠标右键按下了!"), TEXT("鼠标"), MB_OK);
return 0;
case WM_PAINT: //客户区重绘消息
hdc = BeginPaint(hWnd, &ps);
hPen = CreatePen(PS_DASH, 1, RGB(255, 0, 0));
nOldPen = SelectObject(hdc, hPen);
hBrush = CreateSolidBrush(RGB(0, 255, 0));
nOldBrush = SelectObject(hdc, hBrush);
Ellipse(hdc, rect.left, rect.top, rect.right, rect.bottom);
//Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
//MyPolyline(hdc, pts,3);
SelectObject(hdc, nOldPen);
DeleteObject(hPen);
SelectObject(hdc, nOldPen);
DeleteObject(hPen);
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
KillTimer(hWnd, TIME_ID);
return 0;
}
//调用缺省消息处理过程
return DefWindowProc(hWnd, message, wParam, lParam);
} //函数 WinProc 结束
BOOL MyPolyline(HDC hdc, POINT* pts, int cpt)
{
int flag = FALSE;
for (int i = 0; i < cpt; )
{
MoveToEx(hdc, pts[i].x, pts[i].y, NULL);
i++;
LineTo(hdc, pts[i].x, pts[i].y);
if (i == cpt)
flag = TRUE;
}
return flag;
}
BOOL MyPolyPolyline(HDC hdc, POINT* apt, DWORD* asz, DWORD csz)
{
int number = 0;
int i;
int flag = 0;//标志,当函数成功运行时返回1,否则返回0
for (i = 0; i < csz; i++)
{
int j;
MoveToEx(hdc, apt[number].x, apt[number].y, NULL);
for (j = 1; j < asz[i]; j++)
{
LineTo(hdc, apt[number + j].x, apt[number + j].y);
}
number += j;
}
if (i == csz)
flag = 1;
return flag;
}