子窗口,控件与提示框

子窗口,控件与提示框

1 子窗口

子窗口就是一个父窗口里的一个窗口,父窗口也叫主窗口。
子窗口也是窗口,它有自己的回调函数、自己的窗口类、自己的创建。
它位于主窗口里的一个区域,我们可以设置子窗口的大小和位置以及相关属性。
子窗口与主窗口之间是相联系的,它们通过句柄和消息等访问彼此的。

如果是自己新建的子窗口和主窗口一样需要定义消息处理函数,注册,创建才能显示。
而且用CreateWindow函数时需要把“父窗口句柄”这个参数加上。

void CreateWindowA(
  [in, optional]  lpClassName,
  [in, optional]  lpWindowName,
  [in]            dwStyle,
  [in]            x,
  [in]            y,
  [in]            nWidth,
  [in]            nHeight,
  [in, optional]  hWndParent,//父窗口句柄
  [in, optional]  hMenu,
  [in, optional]  hInstance,
  [in, optional]  lpParam

);

子窗口与父窗口之间的交互可以看这篇博客

2 控件

微软提供了几个预定义的窗口类以方便我们的使用。
大多数时间内,我们把它们用在对话框中,所以我们一般就它们叫做子窗口控件。

子窗口控件会自己处理消息,并在自己状态发生改变时发送消息

控件无需注册就可创建。

一些常见的控件使用方法可以看这篇文章

3 使用控件——以按钮为例

#include<cstdio>
#include <windows.h>
#include<cstring>
#define MyBut 1

HANDLE g_hOutput = 0; // 标准输出句柄

// 窗口处理函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
{
	switch (msgID)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_COMMAND:
		int wmId = LOWORD(wParam);
		switch (wmId)
		{
		case MyBut:
			char szText[256] = "click";
			WriteConsole(g_hOutput, szText, strlen(szText), NULL, NULL);
			break;
		}

	}
	return DefWindowProc(hWnd, msgID, wParam, lParam);
}

// 入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow)
{
	AllocConsole(); // 增加Dos
	g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	// 新建窗口类
	WNDCLASS wc = { 0 };
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.hCursor = NULL;// 默认光标
	wc.hIcon = NULL;// 默认图标
	wc.hInstance = hIns;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = "Windows";
	wc.lpszMenuName = NULL; // 无菜单
	wc.style = CS_HREDRAW | CS_VREDRAW;
	// 注册窗口类
	RegisterClass(&wc);
	// 内存中创建窗口
	HWND hWind = CreateWindow("Windows", "windows", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, NULL, NULL);
	// 显示窗口
	ShowWindow(hWind, SW_SHOW);
	UpdateWindow(hWind);

	HWND hwndButton = CreateWindow("BUTTON", "click", WS_CHILD | WS_VISIBLE, 250, 250, 50, 50, hWind, (HMENU)MyBut, hIns, NULL);
	// 消息循环
	MSG nMsg = { 0 };
	while (true)
	{
		if (PeekMessage(&nMsg, NULL, 0, 0, PM_NOREMOVE))
		{
			if (GetMessage(&nMsg, NULL, 0, 0))
			{
				TranslateMessage(&nMsg);
				DispatchMessage(&nMsg);
			}
			else break;
		}
		else
		{
			// 空闲处理
		}
	}
	UnregisterClass("Windows", hIns);
	return 0;
}

有以下几点需要注意:

1 创建时对于子窗口,hWndParent是父窗口句柄;hMenu参数指定子窗口标识符,一个整数值;
而hInstance参数是当前程序的句柄;dwStyle参数一定要把WS_CHILD | WS_VISIBLE选上。

HWND hwndButton = CreateWindow("BUTTON", "click", WS_CHILD | WS_VISIBLE, 250, 250, 50, 50, hWind, (HMENU)MyBut, hIns, NULL);

2对于按钮消息wParam参数的低32位是 ID. 也就是 menu item标记.

case WM_COMMAND:
		int wmId = LOWORD(wParam);
		switch (wmId)
		{
		case MyBut:
			char szText[256] = "click";
			WriteConsole(g_hOutput, szText, strlen(szText), NULL, NULL);
			break;
		}

4 提示框(MessageBox函数)

调用MessageBox函数
会弹出一个提示框。

提示框是一个阻塞函数,所以程序会在此暂停以接收返回值,然后依据返回值作相应操作。

函数参数定义:

int MessageBox(
  [in, optional] HWND    hWnd, // 当前窗口句柄
  [in, optional] LPCTSTR lpText, // 内容
  [in, optional] LPCTSTR lpCaption, // 标题
  [in]           UINT    uType // 样式
);
posted @ 2022-08-15 12:20  DarkLights  阅读(14)  评论(0)    收藏  举报