Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
vermeir_nico_introducing_net_6_getting_started_with_blazor_m.pdf
Скачиваний:
19
Добавлен:
26.06.2023
Размер:
11.64 Mб
Скачать

Chapter 3 Command Line Interface

Figure 3-12.  Adding a project reference through the command line

Some frameworks, extension, etc. come with their own command line-based tool; Entity Framework, for example, ships with a CLI tool, for example, to create migrations or update a database. These tools are managed with the dotnet tool command. Dotnet tool can install tools, list all the installed tools, update or restore them, run them, and uninstall them.

Wrapping Up

In this chapter, we have gone over the most common parts of the extensive CLI tooling that is included with .NET 6. We as developers use these tools more than we realize, since they are the magic behind the buttons and shortcut keys in Visual Studio. Knowing what the capabilities are, and how to find the different options, is important knowledge, not only to have an idea of what is going on under the hood of Visual Studio but also to be able to define build and release pipelines.

64

CHAPTER 4

Desktop Development

I often get the question if there is still use in learning desktop technologies like WPF or WinForms. My answer is always the same: of course there is! There has been a big movement toward the Web the past few years, which definitely makes sense in regard

to ease of deployment and installation. No need to juggle MSI files around, making sure every client computer has the correct version of .NET installed, finding out what version of the software a customer is using, and so on. With web applications, we install the software on a server, and all of our users just use their browsers to use the application. So why are native apps (both desktop and mobile apps) still a thing? The answer is simple, performance and capabilities. The Web, for now, does not have the same level of access to peripherals and operating system as a native app does. As for performance, let’s look at the way an operating system renders its applications. Rendering happens in steps, layer by layer. A WPF application, for example, will render its main window followed by the controls on that specific window; the whole rendering of an application is optimized to draw the user interface as fast as possible to not make the user feel like the application is hanging. If we apply that same logic to a web browser, you’ll understand that the browser’s main window and controls like the back and forward buttons, favorite bar, extension icons, and so on are rendered first. Once everything is on the screen, the browser will start interpreting and rendering the HTML, so the actual user interface of your web application is last to render. Another major difference is threading, JavaScript is single-threaded, so it’s not possible to schedule heavy work on a separate thread. The advice there is to have a server handle the heavy lifting and make your frontend wait for the response, which is a very valid argument, except for applications that need real-time heavy processing, like the software stock brokers use, for example. Every millisecond of delay caused by a request going over the network can cost them money. A native desktop application, running on a powerful client computer, can handle these calculations

with ease.

65

© Nico Vermeir 2022

N. Vermeir, Introducing .NET 6, https://doi.org/10.1007/978-1-4842-7319-7_4

Chapter 4 Desktop Development

.NET 6 comes with multiple choices for desktop development, WPF, WinForms, Windows App SDK, CLI, Blazor Desktop, and MAUI. In this chapter, we’ll take a look at these options, except for Blazor Desktop, and we will discuss that option in the Blazor chapter of this book.

WinAPI

Win32 and Win64, depending on the OS and CPU architecture, are the APIs in Windows that allow applications to run. The API is responsible for everything going on in Windows, from rendering applications and access to the operating system to installation/configuration and so on. It’s the engine under the hood of Windows. Without WinAPI, we simply wouldn’t be able to run applications on Windows. WinAPI is a native C/C++ API, meaning we’d need to write applications in those languages to leverage the WinAPI API set.

With WinAPI, we can build applications that have incredible performance, because we are in an unmanaged world. Languages like C# and Java, for example, are managed languages, meaning that there is a runtime taking care of recovering and managing memory. Unmanaged code, like C or C++, runs much closer to the metal, leaving

the responsibility of reclaiming memory to the developer but gaining performance in return. But this performance comes with a price. It takes longer to develop these

types of applications, and since they are unmanaged they are more prone to memoryrelated bugs. Listing 4-1 shows an example of the C++ code needed to simply draw an empty window on screen. Feel free to copy, compile, and run the code in Listing 4-1 if you have a C++ environment setup, and you will notice that it just works but shows an empty screen.

Listing 4-1.  Drawing an empty window with Win32

#ifndef UNICODE #define UNICODE #endif

#include <windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

66

Chapter 4 Desktop Development

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)

{

// Register the window class.

const wchar_t CLASS_NAME[] = L"Sample Window Class";

WNDCLASS wc = { };

wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.lpszClassName = CLASS_NAME;

RegisterClass(&wc);

// Create the window.

HWND hwnd = CreateWindowEx(

 

0,

 

 

// Optional window styles.

CLASS_NAME,

 

 

// Window class

L"Learn to Program Windows",

// Window text

WS_OVERLAPPEDWINDOW,

// Window style

// Size and

position

 

CW_USEDEFAULT,

CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

NULL,

//

Parent window

 

NULL,

//

Menu

 

hInstance,

//

Instance handle

 

NULL

//

Additional application data

);

 

 

 

if (hwnd == NULL)

{

return 0;

}

ShowWindow(hwnd, nCmdShow);

67

Chapter 4 Desktop Development

// Run the message loop. MSG msg = { };

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return 0;

}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

switch (uMsg)

{

case WM_DESTROY: PostQuitMessage(0); return 0;

case WM_PAINT:

{

PAINTSTRUCT ps;

HDC hdc = BeginPaint(hwnd, &ps);

// All painting occurs here, between BeginPaint and EndPaint. FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1)); EndPaint(hwnd, &ps);

}

return 0;

}

return DefWindowProc(hwnd, uMsg, wParam, lParam);

}

68