One of DirectX - Windows Programming Foundation Framework

DirectX Windows Programming Fundamentals Framework

Preface

DirectX is a series of products created by Microsoft specifically designed for multimedia and gaming Application Programming Interface The internal components can be divided into display part, sound part, input part, and network part according to their properties. Among them Direct3D It belongs to the subset of 3D graphics display in the display section, and Direct3D can be divided into different versions based on their release before and after Direct3D9 Direct3D10 Direct3D11 Direct3D12 ; Introduction to this series of articles The version of D3D will be explained in parentheses in the title , The first article to be introduced will be the Direct3D9 series . For a detailed introduction to DirectX, please click here. As DirectX is a set of calling interfaces, we must write an application program to make calls within the program. This is important for programming windows Provide a brief (detailed) introduction, only covering the parts required to use DirectX.

Introduction to Windows Applications

Those who understand Windows programming know that Windows programs follow Event driven model Usually, Windows programs wait for an event to occur after starting, and only process it after the event occurs, such as mouse clicks, keyboard clicks, window size changes, and so on; Here is a summary of some concepts:
Windows -- Windows operating system
Windows Applications - Applications We Write
Application Window - A window created by a Windows application (possibly multiple)
When we click on the screen, Windows receives the command, and then Windows sends the message to the Windows application. The specific implementation is that each Windows application has a Message queue Sending messages to Windows applications is actually adding messages to the message queue of the Windows application. The Windows application continuously checks the message queue in a message loop, and when a message is detected, it dispatches it to a specific window (an application may have multiple windows). The specific process is quite clear in the following diagram


.

Simple Implementation of Windows Applications

Once we understand the operating principle of Windows applications, we can start programming. Here, we implement a blank window, which can be exited by pressing the ESC key. Clicking with the left mouse button will bring up a "hello world" window
The specific code is as follows (explanations for each module are provided in the comments):

/*windows development required header files 
 contain Windows definition of macros, classes, functions, structures, and other structures required for development* /
#include <windows.h>
HWND MainWindowHandle = 0;                                                              //main window handle, equivalent to the window's ID
bool InitWindowsApp(HINSTANCE instanceHandle, int show);            //initialize window function 
int Run();                                                                                                          //message loop function 
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg,               //message processing function 
                   WPARAM wParam, LPARAM lParam);
/*WinMain function, equivalent to C++ middle main functions are the entry points for program execution* /
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nShowCmd)
{
//if initialization fails, a message window will pop up to prompt 
if (!InitWindowsApp(hInstance, nShowCmd))
{
  ::MessageBox(0, "Init - Failed", "Error", MB_OK);
  return 0;
}
return Run();
}
//implementation of initialization window function 
bool InitWindowsApp(HINSTANCE instanceHandle, int show)
{
//windows customization of window types 
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = instanceHandle;
wc.hIcon = ::LoadIcon(0, IDI_APPLICATION);
wc.hCursor = ::LoadCursor(0, IDC_ARROW);
wc.hbrBackground = static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH));
wc.lpszMenuName = 0;
wc.lpszClassName = "Hello";
//towards Windows system registration window 
if (!::RegisterClass(&wc))
{
  ::MessageBox(0, "RegisterClass - Failed", 0, 0);
  return false;
}
//create based on custom windows 
MainWindowHandle = ::CreateWindow(
  "Hello",
  "Hello",
  WS_OVERLAPPEDWINDOW,
  CW_USEDEFAULT,
  CW_USEDEFAULT,
  CW_USEDEFAULT,
  CW_USEDEFAULT,
  0,
  0,
  instanceHandle,
  0);
//if creation fails, a message window will pop up to prompt 
if (MainWindowHandle == 0)
{
  ::MessageBox(0, "CreateWindow - Failed", 0, 0);
  return false;
}
::ShowWindow(MainWindowHandle, show);           //display window 
::UpdateWindow(MainWindowHandle);                   //perform window refresh 
return true;
}
//definition of message loop function 
int Run()
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));
while (::GetMessage(&msg, 0, 0, 0))
{
  ::TranslateMessage(&msg);
  ::DispatchMessage(&msg);
}
return msg.wParam;
}
//message processing function definition 
LRESULT CALLBACK WndProc(HWND windowHandle, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_LBUTTONDOWN:
  ::MessageBox(0, "Hello, Word", "Hello", MB_OK);
  return 0;
case WM_KEYDOWN:
  if (wParam == VK_ESCAPE)
  {
      ::DestroyWindow(MainWindowHandle);
  }
  return 0;
case WM_DESTROY:
  ::PostQuitMessage(0);
  return 0;
}
return ::DefWindowProc(windowHandle, msg, wParam, lParam);
}

Detailed Introduction to Windows Applications

  1. WinMain function
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nShowCmd)
    The WinMain function is the entry point for running Windows programs, just like c++ Like the main function in, the parameters are defined as follows:
    WINAPI The #define WINAPI __stdcall; statement specifies a calling convention, including how to produce mechanical code to place function call parameters in the stack. Many Windows function calls are declared as WINAPI
    HINSTANCE typedef HINSTANCE_ *HINSTANCE; shows that HINSTANCE It is actually a pointer type
    PSTR typedef CHAR *PSTR; can see that PSTR represents a string pointer
    HInstance The handle to the current Windows application instance (program itself), allocated by the system. When the same program is run multiple times simultaneously, multiple copies of the program are created Execution instance
    HPresInstance By checking the hPrevInstance parameter, it is possible to determine whether its other execution instances are running. In the 32-bit Windows version, this concept has been abandoned, and the second parameter passed to WinMain is always NULL (defined as 0)
    PCmdLine : Command line string used to run the program
    NShowId : Specify the display method of the application window; SW_ SHOWNORMAL : The window is displayed at normal size; SW_ SHOWMAXIMIZED Maximize window display; SW_ SHOWMINNOACTIVE Minimize window display
    MSDN has a detailed introduction to WinMain.

  2. InitWindows App function
    bool InitWindowsApp(HINSTANCE instanceHandle, int show)
    This function first customizes the window type, then registers the window, creates the window, and displays the window. Most of the calls here are system functions, so many things only have a lookup connection attached for easy reference
    WNDCLASS :
    typedef struct tagWNDCLASSA {
    .
    } WNDCLASSA
    typedef WNDCLASSA WNDCLASS;

    It can be seen that WNDCLASS It is a structural type, and the values of each member have a reference range. The specific range is relatively long. Here, an MSDN connection is attached for reference
    : LoadIcon The scope symbol ":" here should be noted that it represents the global scope, that is, calling the global LoadIcon function Three uses of the scope symbol "::" Here is another link posted. Additionally, regarding Usage of the LoadIcon function Here is a search link posted
    : LoadCursor Similar to:: LoadIcon, but with the style of the mouse pointer set to search for connections
    : GetStockObject (WHITE-BRUSH) : Return a handle to a brush, font, or color palette, etc. For specific parameters, refer to Find Connection
    Static_ Cast<> () : static_ Cast is used for type conversion during compilation, and related to it are also Reinterpret_ Cast Dynamic_ Cast . Dynamic_ Cast Used for runtime type conversion Reinterpret_ Cast It is completely reinterpreted according to binary storage

  3. Run function
    Message loop, used to handle messages launched by Windows systems to programs
    MSG :
    typedef struct tagMSG {
    .
    } MSG, *PMSG, *LPMSG;

    It can be seen that MSG is a structure that contains some member information related to messages. Please refer to the specific meanings of each member here