C++同时注册两窗口,点击按钮打开另一窗口

//Aother:CYhuq
//越禾信息:志在记录和技术交流
//QQ:421160052
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#include <iostream>
#include "resource.h"
#include <afxres.h>
using namespace std;
//宏定义参数
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0) //必要的,我是背下来的 
#define IDC_BUTTON1 106
#define MAX_LOADSTRING 100

// ------------------------Global variables(全局变量)---------------------------------
//DLL调用
// 主窗体类名

//TOOP:HINSTANCE 是Windows里的一中数据类型,是用于标示(记录)一个程序的实例。
//它与HMODULE是一样的(通用的,这两种类型最终就是32位无符号长整形)。
//HINSTANCE,分开看就是 HANDLE(句柄) + INSTANCE(实例)
//实例就是一个程序。用qq来举例:你可以开同时开2个qq号,但是你电脑里的qq软件只有一份。
//这2个qq号就是qq的2个实例
HINSTANCE hInst;
HWND hWnd2;
int nCS;
TCHAR szWindowClass[MAX_LOADSTRING]=_T("CYhuq");
TCHAR szWindowClass2[MAX_LOADSTRING] = _T("CYhuq2");
TCHAR szTitle[MAX_LOADSTRING]=_T("Demo");
TCHAR szTitle2[MAX_LOADSTRING] = _T("Demo2");
//TOOP:登陆句柄

// -------------------------需要预定义的函数放置在此代码块种:---------------------------- 
//每个 Windows 桌面应用程序必须具有一个窗口过程函数
//此函数处理应用程序从操作系统中接收的大量消息。 
//例如,如果应用程序的对话框中有“确定”按钮,那么用户单击该按钮时,
//操作系统会向应用程序发送一条消息,通知按钮已被单击。WndProc 负责对该事件作出响应。
//在本例中,相应的响应可能是关闭对话框。。。
ATOM	MyRegisterClass(HINSTANCE hInstance);
ATOM	MyRegisterClass2(HINSTANCE hInstance);
BOOL	InitInstance(HINSTANCE,int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK WndProc2(HWND, UINT, WPARAM, LPARAM);

//-------------------------------------正式内容-----------------------------------------

//入口函数,主函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR IpCmdLine, int nCmdShow)
{
	MSG msg;
	//从资源文件中装载由IDS_APP_TITLE 指定的字符串资源
	//LoadString(hInst, AFX_IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

	//LoadString(hInst, AFX_IDS_APP_TITLE, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInst);
	MyRegisterClass2(hInst);
	//初始化程序实例
	if (!InitInstance(hInstance, nCmdShow))
	{
		return FALSE;
	}
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg); //翻译消息
		DispatchMessage(&msg);  //派遣消息
	}
	return msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	//创建 WNDCLASSEX 类型的窗口类结构。 此结构包含关于窗口的信息
	//例如应用程序图标、窗口背景色、标题栏中显示的名称、窗口过程函数的名称等。
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	//----------------------------------具体参数------------------------------------
	wcex.style = CS_HREDRAW | CS_VREDRAW;//样式
	wcex.lpfnWndProc = WndProc;//设定窗口回调函数
	wcex.cbClsExtra = 0;//为窗口类的额外信息做记录
	wcex.cbWndExtra = 0;//记录窗口实例的额外信息,系统设置为0,如果程序使用WNDCLASSSEX注册一个从资源文件里创建的对话框,则此参数必须设置为DLGWINDOWEXTRA
	wcex.hInstance = hInstance;//窗口实例名
	wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON_HD));//显示上面的图标
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);//窗口光标
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);//背景刷
	wcex.lpszMenuName = NULL;//
	wcex.lpszClassName = szWindowClass;//窗体类名
	wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

	//对已创建的窗口类进行注册。 使用 RegisterClassEx 函数,并将窗口类结构作为参数传递。
	if (!RegisterClassEx(&wcex))
	{
		MessageBox(NULL, _T("Call to RegisterClassEx failed1!"), _T("Win32 Guided Tour"), NULL);
		return 1;
	}
	//对已创建的窗口类进行注册。 使用 RegisterClassEx 函数,并将窗口类结构作为参数传递。
	return RegisterClassEx(&wcex);
}
ATOM MyRegisterClass2(HINSTANCE hInstance)
{
	//创建 WNDCLASSEX 类型的窗口类结构。 此结构包含关于窗口的信息
	//例如应用程序图标、窗口背景色、标题栏中显示的名称、窗口过程函数的名称等。
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	//----------------------------------具体参数------------------------------------
	wcex.style = CS_HREDRAW | CS_VREDRAW;//样式
	wcex.lpfnWndProc = WndProc2;//设定窗口回调函数
	wcex.cbClsExtra = 0;//为窗口类的额外信息做记录
	wcex.cbWndExtra = 0;//记录窗口实例的额外信息,系统设置为0,如果程序使用WNDCLASSSEX注册一个从资源文件里创建的对话框,则此参数必须设置为DLGWINDOWEXTRA
	wcex.hInstance = hInstance;//窗口实例名
	wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON_HD));//显示上面的图标
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);//窗口光标
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);//背景刷
	wcex.lpszMenuName = NULL;//
	wcex.lpszClassName = szWindowClass2;//窗体类名
	wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

	//对已创建的窗口类进行注册。 使用 RegisterClassEx 函数,并将窗口类结构作为参数传递。
	if (!RegisterClassEx(&wcex))
	{
		MessageBox(NULL, _T("Call to RegisterClassEx failed1!"), _T("Win32 Guided Tour"), NULL);
		return 1;
	}
	//对已创建的窗口类进行注册。 使用 RegisterClassEx 函数,并将窗口类结构作为参数传递。
	return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance,int nCmdShow)
{
	HWND hWnd;

	// Store instance handle in our global variable 
	// 将句柄实例存储于全局变量中
	hInst = hInstance;
	nCS=nCmdShow;
	// CreateWindow 函数的参数解释: 
	// szWindowClass: the name of the application 
	// szTitle: the text that appears in the title bar 
	// WS_OVERLAPPEDWINDOW: the type of window to create 
	// CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y) 
	// 500, 100: initial size (width, length) 
	// NULL: the parent of this window 
	// NULL: this application does not have a menu bar 
	// hInstance: the first parameter from WinMain 
	// NULL: not used in this application 
	// 返回的HWND是一个窗口的句柄
	hWnd = CreateWindow(szWindowClass, szTitle, 
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, 
		hInstance, NULL);
	hWnd2= CreateWindow(szWindowClass2, szTitle2,
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL,
		hInstance, NULL);
	if (!hWnd)
	{
		//创建失败,提示返回
		MessageBox(NULL, _T("Call to CreateWindow failed!"), _T("Win32 Guided Tour"), NULL); 
			MessageBox(NULL, "2", _T("Win32 Guided Tour"), NULL);
		return FALSE;
	}
	if (!hWnd2)
	{
		//创建失败,提示返回
		MessageBox(NULL, _T("Call to CreateWindow failed!22222"), _T("Win32 Guided Tour"), NULL);
		MessageBox(NULL, "2", _T("Win32 Guided Tour"), NULL);
		return FALSE;
	}
	// ShowWindow 函数的参数解释: 
	// hWnd: CreateWindow函数返回的窗口句柄 
	// nCmdShow: the fourth parameter from WinMain 
	ShowWindow(hWnd, nCmdShow);
	//ShowWindow(hWnd2, nCmdShow);
	// UpdateWindow函数用于更新窗口指定的区域
	// 如果窗口更新的区域不为空,UpdateWindow函数就发送一个WM_PAINT消息来更新指定窗口的客户区。
	// 函数绕过应用程序的消息队列,直接发送WM_PAINT消息给指定窗口的窗口过程
	// 如果更新区域为空,则不发送消息。
	UpdateWindow(hWnd);
	UpdateWindow(hWnd2);
	// Main message loop: 
	// 添加用于侦听操作系统所发送消息的消息循环。 
	// 当应用程序收到一条消息时,此循环将该消息调度到 WndProc 函数以进行处理。 
	return TRUE;
}
 //  函数: WndProc(HWND, UINT, WPARAM, LPARAM) 
 //  目标:  处理主窗体产生的信息
 //  WM_PAINT消息代表绘制主窗体 
 //  WM_DESTROY消息代表投递一个退出消息并返回 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	switch (message)
	{
	case WM_PAINT:
		//在必要时绘制主窗口
		//要处理 WM_PAINT 消息,首先应调用 BeginPaint
		//然后处理所有的逻辑以及在窗口中布局文本、按钮和其他控件等
		//然后调用 EndPaint。 
		hdc = BeginPaint(hWnd, &ps);

		// -----------------在这段代码对应用程序进行布局------------------------ 
		// 对于此应用程序,开始调用和结束调用之间的逻辑是在窗口中显示字符串 “Hello,World!”。
		// 请注意 TextOut 函数用于显示字符串。
		//TextOut(hdc, 50, 40, greeting, _tcslen(greeting));
		// -----------------------布局模块结束----------------------------------
		RECT rt;
		GetClientRect(hWnd,&rt);

		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
		//创建控件
	case WM_CREATE:
	{
		break;
	}
	//监听键盘消息
	case WM_COMMAND:
	{
		wmId = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		switch (wmId)
		{
			//有按键按下
		case IDC_BUTTON1:
			ShowWindow(hWnd2, nCS);
			break;
		default:
				return DefWindowProc(hWnd, message, wParam, lParam);
		}
	}
	case WM_RBUTTONDOWN:
		//创建button控件
		CreateWindow(TEXT("BUTTON"), TEXT("TEST"), WS_VISIBLE | WS_CHILD, 10, 10,
			100, 20, hWnd, (HMENU)IDC_BUTTON1, hInst, NULL);
		CreateWindow(szWindowClass2, szTitle,
			WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL,
			hInst, NULL);
		break;
	default:
		//DefWindowProc缺省窗口处理函数
		//这个函数是默认的窗口处理函数,我们可以把不关心的消息都丢给它来处理
		return DefWindowProc(hWnd, message, wParam, lParam);
		break;
	}
	return 0;
}
LRESULT CALLBACK WndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	switch (message)
	{
	case WM_PAINT:
		//在必要时绘制主窗口
		//要处理 WM_PAINT 消息,首先应调用 BeginPaint
		//然后处理所有的逻辑以及在窗口中布局文本、按钮和其他控件等
		//然后调用 EndPaint。 
		hdc = BeginPaint(hWnd, &ps);

		// -----------------在这段代码对应用程序进行布局------------------------ 
		// 对于此应用程序,开始调用和结束调用之间的逻辑是在窗口中显示字符串 “Hello,World!”。
		// 请注意 TextOut 函数用于显示字符串。
		//TextOut(hdc, 50, 40, greeting, _tcslen(greeting));
		// -----------------------布局模块结束----------------------------------
		RECT rt;
		GetClientRect(hWnd, &rt);

		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
		//创建控件
	case WM_CREATE:
	{
		break;
	}
	//监听键盘消息
	case WM_COMMAND:
	{
		wmId = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		switch (wmId)
		{
			//有按键按下
		case IDC_BUTTON1:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
	}
	case WM_RBUTTONDOWN:
		//创建button控件
		break;
	default:
		//DefWindowProc缺省窗口处理函数
		//这个函数是默认的窗口处理函数,我们可以把不关心的消息都丢给它来处理
		return DefWindowProc(hWnd, message, wParam, lParam);
		break;
	}
	return 0;
}

在第一个窗口"Demo"建立后,在窗口内点击鼠标右边会新建一个BUTTON,如下:

右键点击
继续点击按钮"TEST",此时会新建立一个窗口:

在这里插入图片描述
第二个窗口和第一个窗口的名字可以一样,这里我为了显示区别,设置了不同的名字"Demo2".

猜你喜欢

转载自blog.csdn.net/hu421160052/article/details/86349840