VS Creates Win32 Applications (Implementing Window Creation)

Keywords: Windows

VS Creates Win32 Application Program (Implementing Window Creation) (II)

The procedure framework is as follows:

I. VS Demonstration Process

Open VS - File - New - Project - Windows Desktop Application

Generate code: (Most functions have been explained in the previous article)

// The first window. cpp: Defines the entry point of the application.
#include "stdafx.h"
#include "First Window. h"
#define MAX_LOADSTRING 100

  // Global variables:
HINSTANCE hInst;                                // Current instance
WCHAR szTitle[MAX_LOADSTRING];                  // Title bar text
WCHAR szWindowClass[MAX_LOADSTRING];            // Main window class name

// Forward declaration of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);    // Register window class
BOOL                InitInstance(HINSTANCE, int);            //Window initialization (create, display, update)
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);     // Message Processing
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);       // Pop-up dialog box

Main function WinMain

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);   //The goal is to avoid the compiler's warning about unreferenced parameters
    UNREFERENCED_PARAMETER(lpCmdLine);       //The goal is to avoid the compiler's warning about unreferenced parameters

    // TODO: Place the code here.

    // Initialize global strings
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_MY, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Execute application initialization:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MY));

    MSG msg;

    // The main message loop:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}

Register window class MyRegisterClass()

//  Function: MyRegisterClass()
//
//  Target: Register window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MY));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_MY);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

Initialization window InitInstance()

//   Function: InitInstance(HINSTANCE, int)
//   Target: Save the instance handle and create the main window
//   Notes:
//        In this function, we save the instance handle in the global variable and
//        Create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // Store instance handles in global variables
//Note: The window class name SZ Windows Class here is the same as the window class registered earlier.
   HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

Message Processing WndProc

//  Functions: WndProc(HWND, UINT, WPARAM, LPARAM)
//  Target: Processing messages from the main window.
//  WM_COMMAND - Processing Application Menu
//  WM_PAINT - Draw Main Window
//  WM_DESTROY - Send an exit message and return

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // Analysis menu selection:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: Add any drawing code using hdc here.
             LPCWSTR text1 = TEXT("VS Win32 window creation");
			TextOut(hdc, 0, 0, text1, lstrlen(text1));
			MessageBox(NULL, TEXT("VS Win32 window creation"), TEXT("hoade"), MB_OK);
			![](https://img-blog.csdnimg.cn/20190731143942499.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MDIxMTgw,size_16,color_FFFFFF,t_70)
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

About Message Processing of Box

// About box message handler.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

Third, the effect of code operation:

IV. Supplementary:

4.1 Use of UNREFERENCED_PARAMETER

The purpose is to avoid the warning of the compiler about unreferenced parameters and to tell the compiler that the variable has been used and that there is no need to detect the warning! Under the VC compiler, if you compile at the highest level, the compiler will point out your very small warnings harshly. When you live with a variable and don't use it, the compiler will alarm you: "warning C4100:''XXXXXX': unreferenced formal parameter." So, in order for the compiler not to need to detect your warning, make the UNREFERENCED_PARAMETER statement.

4.2 LoadStringW()

Function prototype
The resource of the project file (in this case, string, found by ID number) is loaded into the instance's cache (loaded by pointer, and the size of the buffer is specified)

LoadStringW( _In_opt_ HINSTANCE hInstance,    // Instance handle    
             _In_ UINT uID,                   // Existing resource ID (name)    
             _Out_writes_to_(cchBufferMax, return + 1) LPWSTR lpBuffer,//Cache pointer for storing resources  
             _In_ int cchBufferMax);          // The size of the storage resource buffer 

The existing resources are already in the project file. The project file will provide the ID number (that is, the resource name) for the resources. The string we loaded is the resource. A buffer pointer is a pointer to the storage area of the loaded resource. The size of the storage buffer is the size of the storage area for the loaded resources.

4.3 Call in LoadAccelerators()

LoadAccelerators function: Call in the acceleration key table. This function calls into the specified acceleration key table.
Acceleration keys are also called keyboard shortcuts.

Function prototype:

HACCEL LoadAccelerators(HINSTANCE hlnstance,
                         LPCTSTR lpTableName);

Parameters:

hlnstance: Handle to an instance of a module whose executable contains the acceleration key table to be invoked.

IpTableName: A pointer to a null-terminated string containing the name of the accelerated key table to be invoked. Another alternative is that the parameter can specify a resource identifier in the low-bit word of the accelerated keylist resource and zero in the high-bit word. The MADEINTRESOURCE macro can be used to create this value.

Return value:

Return value: If the function call is successful, return the loaded accelerated key table handle [1]. If the function call fails, the return value is NULL. To get more error information, you can call the GetLastError function.

4.4 MSG message structure

Architectural prototype:

MSG msg;
	{
       	HWND        hwnd;     //Window handle
    	UINT        message;  //Message id, message passed in
	    WPARAM      wParam;   //Message Auxiliary Parameters
	    LPARAM      lParam;   //Message Auxiliary Parameters
    	DWORD       time;     //Message delivery time
	    POINT       pt;       //Location of the mouse when the message is generated
	}

4.5 Role of MAKEINTRESOURCEW

MAKEINTRESOURCE is a macro for resource name conversion. This macro converts a numeric type into a pointer type. It has no release problem.

That is, the lpName parameter needs to use MAKEINTRESOURCE, because it requires LPCTSTR type parameter input. Then, the situation is very clear. Where the API or MFC class involving "resources" is LPCTSTR, MAKEINTRESOURCE should be used when the parameter type is LPCTSTR. This is for the case when "resource name" is "digital type".

Posted by ccrevcypsys on Wed, 31 Jul 2019 02:19:13 -0700