Win32 Subwindow and Its Creation Application

Keywords: Windows less

Introduction:
The so-called child window is a window in a parent window, which is also called the main window. Sub-window is also a window, it has its own callback function, its own window class, its own creation. It is located in an area of the main window. We can set the size and location of the sub-window and its related properties. Subwindows are related to the main window, and they access each other through handles and messages.

Special reminder:
The child window control described later is a special kind of child window. The sub-window control does not need us to define the window class. The system has already defined it for us. We can refer to it by ourselves.

Here we first introduce the common sub-windows.

I. Creation of Subwindows

Creation process:
1. Register window class (we register sub-windows after main window registration)
2. Create subwindows (usually created in WS_CREATE message processing, using the CreateWindow function as the main window, with different parameters, WS_CHILD and WS_VISIBLE style)
3. Define the callback function of the sub-window (the callback function of the sub-window and the callback function of the main window are roughly the same, change the name of the function)

1. Register window class

Subwindow class parameters are basically the same as the main window. Generally, only four parameters need to be modified.

// After registering the main window, modify four parameters
wc.cbClsExtra = sizeof(long);    // Reserved space
wc.hIcon = NULL;                 // Icon set to empty
wc.lpfnWndProc = ChildWndProc;   // callback
wc.lpszClassName = TEXT("ChildWindow");   // Subwindow class name

// Register subwindow classes
RegisterClassEx(&wc);

2. Create subwindows

Comparison of CreateWindow parameters:

parameter main window child window
Window class name Definition by oneself Definition by oneself
Window Title Definition by oneself NULL
window style WS_OVERLAPPEDWINDOW WS_CHILDWINDOW and WS_VISIBLE
Horizontal position CW_USEDEFAULT 0 (later modified by the MoveWindow function)
Vertical position CW_USEDEFAULT 0 (later modified by the MoveWindow function)
width CW_USEDEFAULT 0 (later modified by the MoveWindow function)
height CW_USEDEFAULT 0 (later modified by the MoveWindow function)
hwnd NULL hwnd
Menu handle/subID NULL (HMENU) (y << 8 | x) Different sub ID s will do
Entity handle hInstance (HINSTANCE) Get Windows Long (hwnd, GWL_HINSTANCE) or (LPCREATE STRUCT) lParam - > hInstance
Additional parameter lParam NULL NULL

Whether the sub-window display can be modified by calling Show Window function, the size and location of the window can be modified by Move Window function.

// Create 25 sub-windows
case WM_CREATE:
{
	for (i = 0; i < 5; i++)
	{
		for (j = 0; j < 5; j++)
		{
		 childhwnd[i][j]=CreateWindow(TEXT("ChildWindow"), NULL, 
				           WS_CHILD|WS_VISIBLE,
							0, 0, 0 ,0, 
							hwnd, (HMENU)(x++),
						 (HINSTANCE)GetWindowLong (hwnd, GWL_HINSTANCE), NULL);
		}
	}
break;
}

3. Define subwindow callback function

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);  // Main window callback function
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);  // Subwindow callback function

LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	switch(Message)
	{
	case WM_LBUTTONDOWN:
	{
		ShowWindow(hwnd, SW_HIDE);
		break;
	}
	default:
		return DefWindowProc(hwnd, Message, wParam, lParam);   //Let the system process messages, this statement must be added
	}
	return 0;
}

II. THE CONNECTION BETWEEN SUBWINDOWS AND MAIN WINDOWS

1. Main window accesses sub-windows (sending messages)

GetWindowLongPrt Function: Get window information

LONG_PTR GetWindowLongPtr(HWND hWnd,   // Window handle
                          int nIndex);   // Get the specified value of the information
parameter Meaning
GWL_EXSTYLE Gets the extended window style. For more information, see Create Windows Ex.
GWL_STYLE Get window styles
GWLP_WNDPROC Gets a window program indicator, or a handle describing the indicator. If you use this parameter, you must use the CallWindows Proc callback function.
GWLP_HINSTANCE Gets a handle to an application instance.
GWLP_HWNDPARENT If there is only one parent window, get a handle to the parent window.
GWLP_ID Gets the window identifier.
GWLP_USERDATA Getting the data associated with the window is the data left to the user when the application creates the window. The initial value is 0.
DWLP_DLGPROC Gets an indicator of a dialog box, or a handle describing the indicator. If you use this parameter, you must use the CallWindows Proc callback function.
DWLP_MSGRESULT Gets the value of the information being processed in a dialog box.
DWLP_USER Act as an indicator or handle to get additional information about private applications.

GetDlgCtrlID Function: Gets the specified control's ID Number
ID For subforms,Put this in the form ID Number passed to hMenu Parameters.

int GetDlgCtrlID(HWND hwndCtl);  // Subwindow handle

GetDlgItem Function: Gets the specified ID Handle to

HWND childhwnd = GetDlgItem(Parenthwnd,ID);

MoveWindow function: Change the location and size of the specified window
For base windows, location and size depend on the upper left corner of the screen; for child windows, location and size depend on the upper left corner of the client area of the parent window. For Owned windows, location and size depend on the upper left corner of the screen.

BOOL MoveWindow( HWND hWnd, int X, int Y, int nWidth, int nHeight, 
                 BOOL bRepaint; // TRUE redrawing, FALSE not redrawing

SendMessage Function: Sends a specified message to one or more windows
SendMessage The function calls the window program for the specified window until the window program has processed the message before returning.
PostMessage The function returns a message immediately after it is sent to a thread's message queue.

LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam)

2. Subwindows access the main window (send messages)

  • Gets a parent window handle for the specified child window: GetParent
  • Sends the specified message to one or more windows: SendMessage
HWND GetParent(HWND hWnd);

3. The Application of Sub-windows: Turn the Boards

Introduction:
Here, 25 sub-windows are created, 25 sub-windows are visible at the beginning. The main window and the sub-window are respectively pressed by the left mouse button. The main window receives the message to display the sub-window, and the sub-window receives the message to hide the sub-window. ShowWindow can realize this. When the sub-window is displayed, the picture can not be seen, and if the sub-window is not displayed, the picture can be seen. When the sub-window hides, the sub-window disappears and the mouse press message is unacceptable. It should be noted here that when we click on the sub-window, the main window can not receive the key messages, and the sub-window processes the messages through its own callback function.


The code is as follows:

#include <windows.h>
#include"strsafe.h"//secure string operation
// Define callback function
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);

HINSTANCE hInst;   // Used to save the instance handle, used to create a sub-window CreateWindow below
#define NUM 5//macro definition

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	WNDCLASSEX wc;
	HWND hwnd;
	MSG msg;

//  Register the main window class
	memset(&wc, 0, sizeof(wc));
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.lpfnWndProc = WndProc;
	wc.hInstance = hInstance;
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.lpszClassName = TEXT("WindowClass");
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

	if (!RegisterClassEx(&wc)) {
		MessageBox(NULL, TEXT("Window Registration Failed!"), TEXT("Error!"), MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}
 
 // Register subwindow classes
	wc.cbClsExtra = sizeof(long);
	wc.hIcon = NULL;
	wc.lpfnWndProc = ChildWndProc;
	wc.lpszClassName = TEXT("ChildWindow");
	RegisterClassEx(&wc);

// Create the main window
	hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("WindowClass"), TEXT("Caption"), WS_CAPTION|WS_SYSMENU,
		CW_USEDEFAULT, /* x */
		CW_USEDEFAULT, /* y */
		520, /* width */
		542, /* height */
		NULL, NULL, hInstance, NULL);

	hInst = hInstance;   // Save instance handle

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	if (hwnd == NULL) {
		MessageBox(NULL, TEXT("Window Creation Failed!"), TEXT("Error!"), MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}
	while (GetMessage(&msg, NULL, 0, 0) > 0) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}

// Principal function callback function
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc,mdc;
	static int cxClient, cyClient,x=0,cx,cy;
	static HWND childhwnd[NUM][NUM];
	HBITMAP bmp;
	int i, j;
	WCHAR str[100];

	switch (Message)
	{

// Create 25 sub-windows
	case WM_CREATE:
	{
		for (i = 0; i < NUM; i++)
		{
			for (j = 0; j < NUM; j++)
			{
				childhwnd[i][j]=CreateWindowEx(0,TEXT("ChildWindow"), NULL, WS_CHILD|WS_VISIBLE,
							100*i, /* x */
							100*j, /* y */
							98, /* width */
							98, /* height */
							hwnd, (HMENU)(x++), hInst, NULL);
			}
		}
		break;
	}
	
	// Put Zhao Liying-mei's picture on it, as mentioned in the previous blog.
	case WM_PAINT:
	{
		hdc = BeginPaint(hwnd, &ps);
		mdc = CreateCompatibleDC(hdc);
		bmp = (HBITMAP)LoadImage(hInst, MAKEINTRESOURCEW(101), IMAGE_BITMAP, 500, 500, LR_CREATEDIBSECTION);
		SelectObject(mdc, bmp);
		BitBlt(hdc, 0, 0, 500, 500, mdc, 0, 0, SRCCOPY);
		EndPaint(hwnd, &ps);
		break;
	}

   // The main window responds to the left key and displays the sub-windows.
	case WM_LBUTTONDOWN:
	{
		cx = LOWORD(lParam);
		cy = HIWORD(lParam);
		i = cx/100;
		j =  cy/100;
		ShowWindow(childhwnd[i][j], SW_SHOW);  // Display subwindows
	
		break;
	}
	case WM_DESTROY:
	{
		PostQuitMessage(0);
		break;
	}

	default:
		return DefWindowProc(hwnd, Message, wParam, lParam);
	}

	return 0;
}

// Subwindow callback function
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	switch(Message)
	{
	// Subwindows respond to the left key and hide subwindows
	case WM_LBUTTONDOWN:
	{
		ShowWindow(hwnd, SW_HIDE);
		break;
	}
	
	// Other message processing, can't forget ah
	default:
		return DefWindowProc(hwnd, Message, wParam, lParam);
	}
	return 0;
}

The author says:
This world is really good and deceived! The more you don't resist, the less fearful others are, the more you like to cause trouble and bully. She always thinks she is so great. Damn, your family is looking at my mom bullying, right? If something happens, they will be angry with my mom. My mom just went up for a few days and deliberately came to my mom's place to find something. The curse is still so ugly. Really, if I'm not here, otherwise I really want to rush up. My mom is not in good health and can't be in a hurry. My mother's heart aches. This person really is, his personality is questionable also said that my mother, if you are good, how can you and his mother-in-law meet and quarrel, have stayed at his mother's house for more than 20 years, you have the ability not to go back, work in the factory, three days two days is not with this quarrel or that quarrel, and my mother or mother's cousin, there is such a quarrel. Sister ah, I have never seen under the sun, since your family also said, relatives can go, can not go, I also think it is the best, I do not want to touch your light in the future, the road to the sky one side. Others scolded my mother for being upset. I hope you can understand it here.

Posted by gavinbsocom on Thu, 22 Aug 2019 03:06:26 -0700