栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Windows程序设计3——细节内容补充

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Windows程序设计3——细节内容补充

学习视频连接

【SDK开发】《Windows程序设计》_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1us411A7UE?p=9&spm_id_from=pageDriver

一、前面章节的难点 1.1 关闭确认

1、流程

如果我的程序需要在关闭前让用户判断是否确定要关闭窗口,我应该响应哪个消息呢?

如下图所示

2、错误的写法

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;

        switch (message)
        {
        case WM_PAINT:
                hdc = BeginPaint(hwnd, &ps);
                GetClientRect(hwnd, &rect);
                DrawText(hdc, TEXT("大家好,这是我的第一个窗口程序!"), -1, &rect,
                        DT_SINGLELINE | DT_CENTER | DT_VCENTER);
                EndPaint(hwnd, &ps);
                return 0;

		case WM_LBUTTONUP:
				MessageBox(hwnd, TEXT("我被按了一下"), TEXT("我是标题"), MB_OK);
				return 0;

        case WM_DESTROY:
			if (MessageBox(hwnd, TEXT("是否真的关闭?"), TEXT("请确认"), MB_YESNO) == IDYES) {
				PostQuitMessage(0);
			}
			else {
                return 0;
			}
        }

        return DefWindowProc(hwnd, message, wParam, lParam);
}

存在的问题,选择的时候点了否,窗口没有重新打开,并且后台有进程

 

3、正确的写法

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;

        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
            GetClientRect(hwnd, &rect);
            DrawText(hdc, TEXT("大家好,这是我的第一个窗口程序!"), -1, &rect,
                        DT_SINGLELINE | DT_CENTER | DT_VCENTER);
            EndPaint(hwnd, &ps);
            return 0;

		case WM_LBUTTONUP:
			MessageBox(hwnd, TEXT("我被按了一下"), TEXT("我是标题"), MB_OK);
			return 0;

		case WM_CLOSE:
			if (MessageBox(hwnd, TEXT("是否真的关闭?"), TEXT("请确认"), MB_YESNO) == IDYES) {
				DestroyWindow(hwnd);
			}
			else {
                return 0;
			}

        case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
        }

        return DefWindowProc(hwnd, message, wParam, lParam);
}

1.2 程序未响应

如果一个case结束不了,这个程序就未响应了

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;

        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
            GetClientRect(hwnd, &rect);
            DrawText(hdc, TEXT("大家好,这是我的第一个窗口程序!"), -1, &rect,
                        DT_SINGLELINE | DT_CENTER | DT_VCENTER);
            EndPaint(hwnd, &ps);
            return 0;

		case WM_LBUTTONUP:
			while (1) {}
			MessageBox(hwnd, TEXT("我被按了一下"), TEXT("我是标题"), MB_OK);
			return 0;

		case WM_CLOSE:
			if (MessageBox(hwnd, TEXT("是否真的关闭?"), TEXT("请确认"), MB_YESNO) == IDYES) {
				DestroyWindow(hwnd);
			}
			else {
                return 0;
			}

        case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
        }

        return DefWindowProc(hwnd, message, wParam, lParam);
}

点一下屏幕中间,程序就卡住了

二、文本输出 2.1 三大核心部件

我们所调用的大部分 api 都是封装在三大子系统中的

kernel:内核相关  内存管理、文件输入输出、任务管理

user:用户相关  窗口管理、用户界面、GUI

2.2 设备环境

1、定义

设备环境句柄是应用程序使用 GDI 函数的通行证

2、获取设备环境句柄

方法一:响应 WM_PAINT 消息时候使用

hdc = BeginPaint(hwnd, &ps);  // 使用 GDI 函数

EndPaint(hwnd, &ps);

方法二:

hdc = GetDC(hwnd);  // 使用 GDI 函数

ReleaseDC(hwnd, hdc);

3、前面有使用设备环境句柄绘制文本的代码

2.3 TextOut

1、结构体

BOOL TextOut(
  _In_  HDC hdc,
  _In_  int nXStart,
  _In_  int nYStart,
  _In_  LPCTSTR lpString,
  _In_  int cchString
);

2、参数解析:

参数含义
hdc设备环境句柄
nXStart指定用于字符串对齐的基准点的逻辑 x 坐标(有关基准点请看下边备注)
nYStart指定用于字符串对齐的基准点的逻辑 y 坐标
lpString1. 指向将被绘制字符串的指针
2. 该字符串不必以''结束,因为 cchString 参数指定了该字符串的长度
cchStringlpString 字符串的长度(有多少个字符)



3、返回值:

(1) 如果函数调用成功,返回值为非 0

(2) 如果函数调用失败,返回值为 0
 

4、代码:

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;

        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
			TextOut(hdc, 400, 300, TEXT("I love China"), 12);
            EndPaint(hwnd, &ps);
            return 0;

		case WM_LBUTTONUP:
			MessageBox(hwnd, TEXT("我被按了一下"), TEXT("我是标题"), MB_OK);
			return 0;

		case WM_CLOSE:
			if (MessageBox(hwnd, TEXT("是否真的关闭?"), TEXT("请确认"), MB_YESNO) == IDYES) {
				DestroyWindow(hwnd);
			}
			else {
                return 0;
			}

        case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
        }

        return DefWindowProc(hwnd, message, wParam, lParam);
}

 如果字符少于 12,则显示不全;如果字符多余12,则多的部分显示乱码

三、安全的使用字符串 3.1 字符串处理函数

3.2 简单使用循环打印内容
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;

		TCHAR szBuffer[128] = TEXT("I love China!");
		int i;

        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
			for (i = 0; i < 10; i++) {
				TextOut(hdc, 0, i * 20, szBuffer, 13);
			}

            EndPaint(hwnd, &ps);
            return 0;

		case WM_LBUTTONUP:
			MessageBox(hwnd, TEXT("我被按了一下"), TEXT("我是标题"), MB_OK);
			return 0;

		case WM_CLOSE:
			if (MessageBox(hwnd, TEXT("是否真的关闭?"), TEXT("请确认"), MB_YESNO) == IDYES) {
				DestroyWindow(hwnd);
			}
			else {
                return 0;
			}

        case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
        }

        return DefWindowProc(hwnd, message, wParam, lParam);
}

3.3 合并字符串

1、代码

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;

		TCHAR szBuffer[128];
		int i;

        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
			for (i = 0; i < 10; i++) {
				wsprintf(szBuffer, TEXT("%d: %s"), i + 1, TEXT("I love China!"));
				TextOut(hdc, 0, i * 20, szBuffer, 16);
			}

            EndPaint(hwnd, &ps);
            return 0;

		case WM_LBUTTONUP:
			MessageBox(hwnd, TEXT("我被按了一下"), TEXT("我是标题"), MB_OK);
			return 0;

		case WM_CLOSE:
			if (MessageBox(hwnd, TEXT("是否真的关闭?"), TEXT("请确认"), MB_YESNO) == IDYES) {
				DestroyWindow(hwnd);
			}
			else {
                return 0;
			}

        case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
        }

        return DefWindowProc(hwnd, message, wParam, lParam);
}

2、出现的问题:

第 10 行少了感叹号

修改方案1

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;

		TCHAR szBuffer[128];
		int i;

        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
			for (i = 0; i < 10; i++) {
				wsprintf(szBuffer, TEXT("%3d: %s"), i + 1, TEXT("I love China!"));
				TextOut(hdc, 0, i * 20, szBuffer, 18);
			}

            EndPaint(hwnd, &ps);
            return 0;

		case WM_LBUTTONUP:
			MessageBox(hwnd, TEXT("我被按了一下"), TEXT("我是标题"), MB_OK);
			return 0;

		case WM_CLOSE:
			if (MessageBox(hwnd, TEXT("是否真的关闭?"), TEXT("请确认"), MB_YESNO) == IDYES) {
				DestroyWindow(hwnd);
			}
			else {
                return 0;
			}

        case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
        }

        return DefWindowProc(hwnd, message, wParam, lParam);
}

 

修改方案2

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;

		TCHAR szBuffer[128];
		int i;

        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
			for (i = 0; i < 10; i++) {
				wsprintf(szBuffer, TEXT("%d: %s"), i + 1, TEXT("I love China!"));
				TextOut(hdc, 0, i * 20, szBuffer, lstrlen(szBuffer));
			}

            EndPaint(hwnd, &ps);
            return 0;

		case WM_LBUTTONUP:
			MessageBox(hwnd, TEXT("我被按了一下"), TEXT("我是标题"), MB_OK);
			return 0;

		case WM_CLOSE:
			if (MessageBox(hwnd, TEXT("是否真的关闭?"), TEXT("请确认"), MB_YESNO) == IDYES) {
				DestroyWindow(hwnd);
			}
			else {
                return 0;
			}

        case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
        }

        return DefWindowProc(hwnd, message, wParam, lParam);
}

 

3.4 缓冲区溢出

1、缓冲区大小为 12

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;

		TCHAR szBuffer[10];
		int i;

        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
			for (i = 0; i < 10; i++) {
				wsprintf(szBuffer, TEXT("%d: %s"), i + 1, TEXT("I love China!"));
				TextOut(hdc, 0, i * 20, szBuffer, lstrlen(szBuffer));
			}

            EndPaint(hwnd, &ps);
            return 0;

		case WM_LBUTTONUP:
			MessageBox(hwnd, TEXT("我被按了一下"), TEXT("我是标题"), MB_OK);
			return 0;

		case WM_CLOSE:
			if (MessageBox(hwnd, TEXT("是否真的关闭?"), TEXT("请确认"), MB_YESNO) == IDYES) {
				DestroyWindow(hwnd);
			}
			else {
                return 0;
			}

        case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
        }

        return DefWindowProc(hwnd, message, wParam, lParam);
}

2、没有设置结束点

lstrlen 判断结束点是找到最近的一个 ''

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;

		TCHAR szBuffer[] = {'A', 'B', 'c', 'D'};
		int i, j;

        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
			for (i = 0; i < 10; i++) {
				// wsprintf(szBuffer, TEXT("%d: %s"), i + 1, TEXT("I love China!"));
				j = lstrlen(szBuffer);
				TextOut(hdc, 0, i * 20, szBuffer, j);
			}

            EndPaint(hwnd, &ps);
            return 0;

		case WM_LBUTTONUP:
			MessageBox(hwnd, TEXT("我被按了一下"), TEXT("我是标题"), MB_OK);
			return 0;

		case WM_CLOSE:
			if (MessageBox(hwnd, TEXT("是否真的关闭?"), TEXT("请确认"), MB_YESNO) == IDYES) {
				DestroyWindow(hwnd);
			}
			else {
                return 0;
			}

        case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
        }

        return DefWindowProc(hwnd, message, wParam, lParam);
}

3.5 安全的字符串处理函数

 

题目:要求打印10行字符串到窗口上,然后要求每行显示出行号

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/884057.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号