Create a traditional Windows Desktop application (C++)

Benny Hill 20 Reputation points
2024-04-08T17:52:01.1633333+00:00

Hello !

"I have Visual Studio 2022 and have followed the instructions for creating a traditional Windows Desktop application (C++) available on the page https://learn.microsoft.com/en-us/cpp/windows/walkthrough-creating-windows-desktop-applications-cpp?view=msvc-170.

When I build the file, I get several errors.

Error (active) E0018 expected a ')' 134 Warning C4267 'argument': conversion from 'size_t' to 'int', possible loss of data 132 Error LNK2019 unresolved external symbol main referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) Error LNK1120 1 unresolved externals

Is there anyone who can help me? It would just be so nice to see it work.

/ / Benny

The code is

// HelloWindowsDesktop.cpp

// compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c

#include <windows.h>

#include <stdlib.h>

#include <string.h>

#include <tchar.h>

// Global variables

// The main window class name.

static TCHAR szWindowClass[] = _T("DesktopApp");

// The string that appears in the application's title bar.

static TCHAR szTitle[] = _T("Windows Desktop Guided Tour Application");

// Stored instance handle for use in Win32 API calls such as FindResource

HINSTANCE hInst;

// Forward declarations of functions included in this code module:

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR     lpCmdLine,
_In_ int       nCmdShow
)

{
WNDCLASSEX 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(wcex.hInstance, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);

if (!RegisterClassEx(&wcex))
{
    MessageBox(NULL,
        _T("Call to RegisterClassEx failed!"),
        _T("Windows Desktop Guided Tour"),
        NULL);

    return 1;
}

// Store instance handle in our global variable
hInst = hInstance;

// The parameters to CreateWindowEx explained:
// WS_EX_OVERLAPPEDWINDOW : An optional extended window style.
// szWindowClass: the name of the application
// szTitle: the text that appears in the title bar
// WS_OVERLAPPEDWINDOW: the type of window to create
// CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
// 500, 100: initial size (width, length)
// NULL: the parent of this window
// NULL: this application does not have a menu bar
// hInstance: the first parameter from WinMain
// NULL: not used in this application
HWND hWnd = CreateWindowEx(
    WS_EX_OVERLAPPEDWINDOW,
    szWindowClass,
    szTitle,
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT,
    500, 100,
    NULL,
    NULL,
    hInstance,
    NULL
);

if (!hWnd)
{
    MessageBox(NULL,
        _T("Call to CreateWindow failed!"),
        _T("Windows Desktop Guided Tour"),
        NULL);
    return 1;
}

// The parameters to ShowWindow explained:
// hWnd: the value returned from CreateWindow
// nCmdShow: the fourth parameter from WinMain
ShowWindow(hWnd,
    nCmdShow);

UpdateWindow(hWnd);

// Main message loop:
MSG msg;

while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

return (int)msg.wParam;
}

//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_PAINT    - Paint the main window
//  WM_DESTROY  - post a quit message and return
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("Hello, Windows desktop!");

switch (message)
{
case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);
    // Here your application is laid out.
    // For this introduction, we just print out "Hello, Windows desktop!"
    // in the top left corner.
    TextOut(hdc,
        5, 5,
     // End application-specific layout section.
    EndPaint(hWnd, &ps);
    break;

case WM_DESTROY:
    PostQuitMessage(0);
    break;

default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    break;
}

return 0;
}
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,423 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,530 questions
{count} votes

Accepted answer
  1. RLWA32 40,471 Reputation points
    2024-04-08T21:26:54.7133333+00:00

    The warning about converting from size_t to int is because in a 64-bit build a size_t is a 64-bit type while an int is a 32-bit type. In a 32-bit build this warning is not issued because both size_t and int are 32-bit types. There are several types that have different sizes based upon whether they are used in a 64-bit build or a 32-bit build. All of this is normal.

    Successful 64-bit build

    Good64

    Successful 32-bit build

    Good32

    The LNK2019 error is probably caused because when following the walk-through you created an Empty Console Application project by mistake instead of an Empty Desktop Application project. You can start over and create the correct project type or change the project's Linker->System->SubSystem property so that it appears as shown below. Then rebuild.

    Subsystem

    3 people found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Benny Hill 20 Reputation points
    2024-04-17T14:37:55.3733333+00:00

    Now I have tried everything but the Enter-button seems not be working like my save-button. If you can find a solution I would be so glad to know. Here's my code:

    #include <windows.h>

    #include <tchar.h>

    #include <fstream>

    #include <string>

    // Global variables

    static TCHAR szWindowClass[] = _T("DesktopApp");

    static TCHAR szTitle[] = _T("Namnlista");

    // Function to save names to a text file

    void SaveNamesToFile(const std::wstring& filePath, const std::wstring& name) {

    std::wofstream outFile(filePath, std::ios::app);
    
    if (outFile.is_open()) {
    
        outFile << name << std::endl;
    
        outFile.close();
    
    }
    

    }

    // Forward declarations of functions included in this code module:

    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

    int WINAPI WinMain(

    _In_ HINSTANCE hInstance,
    
    _In_opt_ HINSTANCE hPrevInstance,
    
    _In_ LPSTR     lpCmdLine,
    
    _In_ int       nCmdShow
    

    )

    {

    WNDCLASSEX 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(wcex.hInstance, IDI_APPLICATION);
    
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    
    wcex.lpszMenuName = NULL;
    
    wcex.lpszClassName = szWindowClass;
    
    wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
    
    if (!RegisterClassEx(&wcex))
    
    {
    
        MessageBox(NULL,
    
            _T("Call to RegisterClassEx failed!"),
    
            szTitle,
    
            NULL);
    
        return 1;
    
    }
    
    // Create the text file with full path
    
    TCHAR szFilePath[MAX_PATH];
    
    GetModuleFileName(NULL, szFilePath, MAX_PATH);
    
    std::wstring fullPath(szFilePath);
    
    fullPath = fullPath.substr(0, fullPath.find_last_of('\\'));
    
    fullPath += _T("\\names.txt");
    
    std::wofstream createFile(fullPath);
    
    // The parameters to CreateWindowEx explained:
    
    HWND hWnd = CreateWindowEx(
    
        WS_EX_OVERLAPPEDWINDOW,
    
        szWindowClass,
    
        szTitle,
    
        WS_OVERLAPPEDWINDOW,
    
        CW_USEDEFAULT, CW_USEDEFAULT,
    
        800, 600,
    
        NULL,
    
        NULL,
    
        hInstance,
    
        NULL
    
    );
    
    if (!hWnd)
    
    {
    
        MessageBox(NULL,
    
            _T("Call to CreateWindow failed!"),
    
            szTitle,
    
            NULL);
    
        return 1;
    
    }
    
    ShowWindow(hWnd,
    
        nCmdShow);
    
    UpdateWindow(hWnd);
    
    // Main message loop:
    
    MSG msg;
    
    while (GetMessage(&msg, NULL, 0, 0))
    
    {
    
        TranslateMessage(&msg);
    
        DispatchMessage(&msg);
    
    }
    
    return (int)msg.wParam;
    

    }

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

    {

    switch (message)
    
    {
    
    case WM_CREATE:
    
        // Create edit control to input names
    
        CreateWindow(_T("EDIT"), _T(""), WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | ES_WANTRETURN,
    
            20, 40, 200, 25, hWnd, (HMENU)1, NULL, NULL);
    
        // Create button to save names
    
        CreateWindow(_T("BUTTON"), _T("Spara"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    
            20, 80, 100, 30, hWnd, (HMENU)2, NULL, NULL);
    
        break;
    
    case WM_COMMAND:
    
        if (LOWORD(wParam) == 2 && HIWORD(wParam) == BN_CLICKED) {
    
            // Save button clicked
    
            HWND hEdit = GetDlgItem(hWnd, 1);
    
            int len = GetWindowTextLength(hEdit);
    
            if (len > 0) {
    
                TCHAR* buffer = new TCHAR[len + 1];
    
                GetWindowText(hEdit, buffer, len + 1);
    
                SaveNamesToFile(_T("C:\\Mr T\\Mitt Visual Studio mapp\\Namnlista2\\names.txt"), buffer); // Update with your full path
    
                delete[] buffer;
    
                SetWindowText(hEdit, _T("")); // Clear edit control
    
            }
    
        }
    
        break;
    
    case WM_KEYDOWN:
    
        // Check if Enter key is pressed
    
        if (wParam == VK_RETURN) {
    
            // Simulate a button click for Spara button
    
            SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(2, BN_CLICKED), (LPARAM)GetDlgItem(hWnd, 2));
    
        }
    
        break;
    
    case WM_PAINT:
    
    {
    
        PAINTSTRUCT ps;
    
        HDC hdc = BeginPaint(hWnd, &ps);
    
        EndPaint(hWnd, &ps);
    
        break;
    
    }
    
    case WM_DESTROY:
    
        PostQuitMessage(0);
    
        break;
    
    default:
    
        return DefWindowProc(hWnd, message, wParam, lParam);
    
        break;
    
    }
    
    return 0;
    

    }