Windows程序设计实验四

发布于:2022-11-09 ⋅ 阅读:(425) ⋅ 点赞:(0)

面向对象编程技术

实验四实验报告

 

目录

1 实验要求

1.1 对话框相关内容

1.1.1 研究对话框的使用方式,创建新工程

1.1.2 处理WM_PAINT消息,输出文本内容

1.1.3 增加菜单资源

1.1.4 自定义对话框

1.1.5 使用通用颜色对话框,更改文本

1.1.6 编写对话框处理函数

1.1.7 增加菜单命令响应代码

2 实验过程及结果

2.1 创建工程

2.1.1 创建MyDlg工程

2.1.2 创建MyDGI工程

2.2 程序流程和数据模型分析

2.2.1 增加对WM_PAINT消息的处理,在窗口客户区输出文本

2.2.2 增加菜单资源

2.2.3 增加快捷键设置

2.2.4 快捷菜单设置

2.2.5 自定义对话框

2.2.6 图形绘制函数的使用

2.2.7 绘图函数

2.2.8 画笔与画刷的使用

2.2.9 在WM_CREATE消息中增加设置定时器的代码

2.3 问题及解决方案

2.3.1 自定义MyPolyline函数替代Polyline库函数

2.3.2 自定义MyPolyPolyline函数替代PolyPolyline函数

2.3.3 自定义MyPolyPolygon函数替代PolyPolygon函数

3 实验总结

3.1 对话框

3.1.1 对话框的分类:

3.1.2 对话框的使用过程:

3.1.3 对话框窗口处理函数

3.2 绘图

3.2.1 颜色值的表示

3.2.2 点、线、图形的绘制

3.2.3 画笔与画刷的使用

4 附录 关键代码

 
  1. 实验要求
    1. 对话框相关内容
      1. 研究对话框的使用方式,创建新工程
      2. 处理WM_PAINT消息,输出文本内容
      3. 增加菜单资源
      4. 自定义对话框
      5. 使用通用颜色对话框,更改文本
      6. 编写对话框处理函数
      7. 增加菜单命令响应代码
  2. 实验过程及结果
    1. 创建工程
      1. 创建MyDlg工程

创建MyDlg工程用于完成本次实验要求的第一部分——对话框相关内容。在创建Windows桌面应用程序后,完成下列步骤:

  1. 按照“属性——>配置属性——>高级——>字符集——>未设置”的步修改字符集
  2. 将解决方案平台修改为X86
  3. “属性——>链接器——>系统——>子系统——>窗口进行修改
  4. 完成上面三步后,复制Windows 应用程序基本框架的内容进来,进行修改

图 1 MyDlg工程

      1. 创建MyDGI工程

创建MyDlg工程用于完成本次实验要求的第二部分——图形绘制函数的使用。在创建Windows桌面应用程序后,完成下列步骤:

  1. 按照“属性——>配置属性——>高级——>字符集——>未设置”的步修改字符集
  2. 将解决方案平台修改为X86
  3. “属性——>链接器——>系统——>子系统——>窗口进行修改
  4. 完成上面三步后,复制Windows 应用程序基本框架的内容进来,进行修改

图 2 MyGDI工程

    1. 程序流程和数据模型分析
      1. 增加对WM_PAINT消息的处理,在窗口客户区输出文本

在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 文本输出结果

      1. 增加菜单资源

增加菜单资源总体分为三步,如图 3

图 4 菜单资源步骤

  • ID。

  

图 5 新建菜单资源

  

图 6 包含菜单

      1. 增加快捷键设置
  1. 在加速键资源中定义加速键

(为了避免冗余,暂时只处理两个菜单命令的快捷键),如图 6

图 7 定义快捷键表

  1. 消息循环前装载加速键表

/*

*装载加速键表

*/

HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MYDLG_Accelerator));

使用LoadAccelerators()函数,第一个参数为当前程序实例句柄,第二个参数为快捷键资源ID。

  1. 修改消息循环

/*

*修改后的消息循环

*/

while (GetMessage(&msg, NULL, 0, 0))

{

if (!TranslateAccelerator(ghWnd, hAccel, &msg))//不是加速键

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

图 8 快捷键命令响应

由图 7可以看出,此时并未点击上方菜单栏,仅仅CTRL+M就新建了文件(举例子,仅仅调用了MessageBox函数)。

      1. 快捷菜单设置

快捷菜单又叫做上下文菜单,一般是为了方便用户而设置,用户点击鼠标右键就会弹出。设置快捷菜单分为两步。

  1. 在主窗口消息处理函数里装载快捷菜单

/*

*装载快捷菜单

*/

HMENU hPopMenu = LoadMenu((HINSTANCE)GetWindowLong(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDR_MyDlg_MENU));

hPopMenu = GetSubMenu(hPopMenu, 0);

使用LoadAccelerators()函数,第一个参数为当前程序实例句柄,第二个参数为菜单资源ID,并选中第一列菜单作为上下文菜单。

  1. 在鼠标消息里进一步设置

/*

*处理鼠标右键单击消息

*/

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 快捷菜单响应

      1. 自定义对话框

自定义对话框的步骤如

图 10 自定义对话框流程图

  1. 首先建立想要的对话框模式图,为了方便后面的使用,注意修改ID

图 11 对话框模板

  1. 接着编写对话框消息处理函数,记得在前面声明函数头。

/*

*对话框消息处理函数

*/

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里

  1. 激活对话框

/*

*菜单命令,激活对话框

*/

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;

}

  1. 最后将菜单命令与对话框命令结合起来,验证功能的实现。

图 12 初始状态

图 13 点击“更改文本颜色”

图 14 点击“选择颜色”

图 15 选择红色

图 16 自动显示RGB(255, 0, 0)

图 17 文本被设置为红色

      1. 图形绘制函数的使用

(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. 绘图函数

(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 绘制椭圆

      1. 画笔与画刷的使用

/*

*使用画笔和画刷绘制并填充椭圆形

*/

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 使用画笔和画刷绘制并填充椭圆形

      1. 在WM_CREATE消息中增加设置定时器的代码
  • 用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 定时器消息的处理

    1. 问题及解决方案
      1. 自定义MyPolyline函数替代Polyline库函数

/*

*自定义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库函数的运行结果一致。

      1. 自定义MyPolyPolyline函数替代PolyPolyline函数

/*

*自定义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;

}

      1. 自定义MyPolyPolygon函数替代PolyPolygon函数

/*

*自定义MyPolyPolygon函数

*/

  1. 实验总结
    1. 对话框
      1. 对话框的分类:

(1)模式对话框 - 当对话框显示时,会禁止其他窗口的输入等用户交互操作。

(2)非模式对话框 - 在对话框显示后,其他窗口同样可以接收输入等用户交互操作。

      1. 对话框的使用过程:
  1. 对话框窗口处理函数
  2. 添加窗口资源
  3. 创建对话框(模式对话框和非模式对话的创建不一样)
  4. 关闭对话框(模式对话框和非模式对话的删除也不一样)
      1. 对话框窗口处理函数

BOOL CALLBACK DialogProc(

HWND hwndDlg, //窗口句柄

UINT uMsg, //消息ID

WPARAM wParam, //消息参数

LPARAM lParam //消息参数

);

返回TRUE表示DialogProc函数中处理了这个消息,缺省处理函数不需要处理。

返回FALSE表示DialogProc函数未处理这个消息,交给缺省处理函数处理。

    1. 绘图
      1. 颜色值的表示

一个颜色的值可以用COLORREF表示,使用宏RGB可以给COLORREF赋值,并且可以通过GetRValue/GetGValue/GetBValue这三个函数来获取宏RGB中的每个值。

      1. 点、线、图形的绘制
  1. 点的使用

GetPixel函数可以获取指定点点颜色

SetPixel函数可以设置点的颜色,该函数的返回值为以前的颜色。

  1. 线的使用

MoveToEx函数,移动到指定点

LineTo函数从当前点到指定点绘制一条直线。

  1. 封闭图形的绘制函数

Rectangle绘制矩形

Ellipse绘制圆形

RoundRect绘制圆角矩形

Arc绘制弧线

      1. 画笔与画刷的使用
  1. 画笔(HPEN)的使用

1)创建画笔 - CreatePen

2)将画笔应用到DC中 - SelectObject,该函数返回原来的GDI绘图对象的句柄,需要保存起来,绘图结束后需要在将原来的GDI对象在重新选入替代自己创建的画笔

3)绘图

4)取出DC中的画笔,将原来的画笔,使用SelectObject函数放入设备DC中,就会将我们创建的画笔取出。

5)释放画笔 - DeleteObject

  1. 画刷的使用

1)创建画刷

CreateSolidBrush - 创建实心画刷

CreateHatchBrush - 创建阴影画刷

CreatePatternBrush - 创建位图画刷

2)将画刷应用到DC中 - SelectObject

3)绘图

4)将画刷从DC中取出 - SelectObject

5)删除画刷 - DeleteObject

    1. 定时器
      1. 定时器消息

可以在程序中设置定时器,当到达时间间隔时,定时器会向窗口发送一个WM_TIMER消息,定时器的精度为毫秒,但是精准度很低。

消息的参数

WPARAM - 定时器ID

LPARAM - 定时器处理函数的指针

      1. 定时器的使用步骤

创建定时器

UINT SetTimer(

HWND hWnd,  //定时器窗口句柄

UINT nIDEvent, //定时器ID

UINT uElapse,  //时间间隔

TIMERPROC lpTimerFunc //定时器处理函数指针

);创建成功,返回非0.

说明:当lpTimerFunc设置为NULL时,使用窗口处理函数作为定时器处理函数,否则就使用定时器处理函数处理定时器消息

消息处理 WM_TIMER

关闭定时器

BOOL KillTimer(

HWND hWnd,  //定时器窗口句柄

UINT uIDEvent  //定时器ID

);

  1. 附录 关键代码

/*******************************************************************

程序: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;

}

本文含有隐藏内容,请 开通VIP 后查看