Win32_SDK_非模态对话框(非模态对话框窗口的销毁,模态与非模态对比,计算器项目练习)

本文介绍了模态与非模态对话框的区别,并通过一个计算器项目的实现,展示了如何在Windows环境下使用Visual Studio 2022创建这两种对话框。文章详细解析了代码流程,包括对话框的初始化、消息处理、按键事件及计算逻辑,并提供了资源文件和头文件的内容。通过这个项目,读者可以深入理解模态与非模态对话框在实际开发中的运用。

1. 模态对话框与非模态对话框对比

  • 模态对话框是通过DialogBox函数生成窗口,且函数的返回值是EndDialog函数传递的。EndDialog是销毁窗口
  • 非模态对话框CreateDialog 和ShowWindow 显示一个窗口,使用DestroyWindow来销毁对话框。EndDialog是隐藏窗口,没有真正的销毁

需要注意

  1. 非模态对话框作为主窗口时,需要写消息循环,且需要PostQuitMessage来退出主循环。
  2. 如果模态对话框作为主窗口,不需要写消息循环
  3. 一般是模态对话框来启动非模态对话框

2. 计算器项目练习模态与非模态对话框

平台windows 工具Visual Studio2022

resource.h

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 Calc.rc 使用
//
#define IDD_MAIN_CALC                   101
#define IDI_ICON1                       103
#define IDC_BNT_REM                     1002
#define IDC_BNT_DELEAT                  1003
#define IDC_BNT_CLEAR                   1004
#define IDC_BNT_DIV                     1005
#define IDC_BNT_NUM7                    1006
#define IDC_BNT_NUM8                    1007
#define IDC_BNT_SUB                     1008
#define IDC_BNT_NUM9                    1009
#define IDC_BNT_NUM4                    1010
#define IDC_BNT_NUM5                    1011
#define IDC_BNT_MIN                     1012
#define IDC_BNT_NUM6                    1013
#define IDC_BNT_NUM1                    1014
#define IDC_BNT_NUM2                    1015
#define IDC_BNT_ADD                     1016
#define IDC_BNT_NUM3                    1017
#define IDC_BNT_ADDORMIN                1018
#define IDC_BNT_NUM0                    1019
#define IDC_BNT_RET                     1020
#define IDC_BNT_POINT                   1021
#define IDC_STATIC_PERTEXT              1022
#define IDC_STATIC_SHOWTEXT             1023

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        104
#define _APS_NEXT_COMMAND_VALUE         40001
#define _APS_NEXT_CONTROL_VALUE         1023
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

Calc.h

#pragma once
#include<Windows.h>
#include"resource.h"
#include<string>
#include<map>
#include <functional>

HINSTANCE g_hInstance;

std::wstring ShowText;//保存计算器显示的字符串
std::wstring PreText;
bool init = false;//判断字符串是否删除到0
bool is_op = false;//判断是否按下操作按钮
char op = 0;//记录要的操作
double num = 0.0;//记录被操作数
double ret = 0.0;

INT_PTR CALLBACK CalcProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	switch (msg)
	{
	case WM_INITDIALOG:
	{
		//加载窗口图标
		HICON Hicon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON1));

		//发送设置窗口图标的消息
		SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)Hicon);//设置大图标
		SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)Hicon);//设置小图标
		//设置字体
		HFONT hfont=CreateFont(32, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET
			, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH
			, L"黑体");
		HFONT hfont_pre = CreateFont(16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET
			, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH
			, L"黑体");
		//获取控件
		HWND text_hwnd=GetDlgItem(hwnd, IDC_STATIC_SHOWTEXT);
		HWND pre_hwnd = GetDlgItem(hwnd, IDC_STATIC_PERTEXT);
		SendMessage(text_hwnd, WM_SETFONT, WPARAM(hfont), 0);
		SendMessage(pre_hwnd, WM_SETFONT, WPARAM(hfont_pre), 0);
		break;
	}
	case WM_COMMAND:
	{
		init = false;
		//包装器,包装运算
		std::map<char, std::function<float(float, float)>>opMap =
		{
		  {'+',[](float x,float y) {return x + y; }},
		  {'-',[](float x,float y) {return x - y; }},
		  {'*',[](float x,float y) {return x * y; }},
		  {'/',[](float x,float y) {return x / y; }},
		};

		switch (LOWORD(wParam))
		{
		case IDC_BNT_NUM0:
			//宽字符连接
			ShowText += L"0";
			break;
		case IDC_BNT_NUM1:
			ShowText += L"1";
			break;
		case IDC_BNT_NUM2:
			ShowText += L"2";
			break;
		case IDC_BNT_NUM3:
			ShowText += L"3";
			break;
		case IDC_BNT_NUM4:
			ShowText += L"4";
			break;
		case IDC_BNT_NUM5:
			ShowText += L"5";
			break;
		case IDC_BNT_NUM6:
			ShowText += L"6";
			break;
		case IDC_BNT_NUM7:
			ShowText += L"7";
			break;
		case IDC_BNT_NUM8:
			ShowText += L"8";
			break;
		case IDC_BNT_NUM9:
			ShowText += L"9";
			break;
		case IDC_BNT_CLEAR:
			PreText.clear();
			ShowText.clear();
			ret = 0;
			num = 0;
			op = 0;
			SetDlgItemText(hwnd, IDC_STATIC_SHOWTEXT, L"0");
			init = true;
			break;
		case IDC_BNT_DELEAT:
		{
			if (ShowText.size() == 0) {
				SetDlgItemText(hwnd, IDC_STATIC_SHOWTEXT, L"0");
				init = true;
			}
			else if (ShowText.size() > 0) {
				ShowText.pop_back();
				if (ShowText.size() == 0) {
					SetDlgItemText(hwnd, IDC_STATIC_SHOWTEXT, L"0");
					init = true;
				}
			}
			break;
		}
		case IDC_BNT_ADD:
		{
			if (ShowText.size() != 0) {
				if (op != 0) {
					//此时已经有操作符,说明没有按=号,需要计算
					//这里先不处理
					break;
				}
				op = '+';
				ret = _wtoi(PreText.c_str());
				PreText = ShowText;
				PreText += L"+";
				ShowText.clear();
			}
			break;
		}
		case IDC_BNT_MIN:
		{
			if (ShowText.size() != 0) {
				if (op != 0) {
					break;
				}
				op = '-';
				PreText = ShowText;
				ret = _wtoi(PreText.c_str());
				PreText += L"-";
				ShowText.clear();
			}
			break;
		}
		case IDC_BNT_SUB:
		{
			if (ShowText.size() != 0) {
				if (op != 0) {
					break;
				}
				op = '*';
				PreText = ShowText;
				ret = _wtoi(PreText.c_str());
				PreText += L"×";
				ShowText.clear();
			}
			break;
		}
		case IDC_BNT_DIV:
		{
			if (ShowText.size() != 0) {
				if (op != 0) {
					break;
				}
				op = '/';
				PreText = ShowText;
				ret = _wtoi(PreText.c_str());
				PreText += L"÷";
				ShowText.clear();
			}
			break;
		}
		case IDC_BNT_RET:
		{
			if (op != 0) {
				num = _wtoi(ShowText.c_str());
				PreText += std::to_wstring(num);
				ret = opMap[op](ret, num);
				ShowText = std::to_wstring(ret);
				//清空符号
				op = 0;
			}
			break;
		}
		/*case IDC_BNT_REM:
		{
			double num= _wtoi(ShowText.c_str());
			ShowText = std::to_wstring((int)num*100);
			break;
		}
		case IDC_BNT_POINT:
			ShowText += L".";
			break;*/
		default:
			break;
		}
		//设置文本
		if (init == false) {
			SetDlgItemText(hwnd, IDC_STATIC_SHOWTEXT, ShowText.c_str());
		}
		SetDlgItemText(hwnd, IDC_STATIC_PERTEXT, PreText.c_str());
		break;
	}
	case WM_CLOSE:
		EndDialog(hwnd, IDOK);
		break;
	default:
		break;
	}
	return FALSE;
}

Calc.cpp

#include"Calc.h"

extern HINSTANCE g_hInstance;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow) {
	g_hInstance = hInstance;
	//主窗口
	DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN_CALC), nullptr, CalcProc);
	return 0;
}  

在这里插入图片描述

3. 代码位置

Github

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BaiRong-NUC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值