I am fairly new to Windows Desktop programming and am having trouble figuring out how to setup a linker in VS Code to use the Win32 API, or if that is even in fact my issue. Namely my code seems to compile fine but I receive but I get linker errors of unresolved external symbols to basic Windows functions like CreateWindowExW and DispatchMessage.
Executing task: Build with Microsoft (R) MSVC C/C++ Version 19.35.32217.1 for x86
Starting build...
cl.exe /Zi /MT /MTd /O2 /EHsc /nologo /std:c++20 /FeC:\source\StarTrekArmada\src/Output/NewArmada.exe C:\source\StarTrekArmada/src/*.cpp
cl : Command line warning D9025 : overriding '/MT' with '/MTd'
WinMain.cpp
WinMain.obj : error LNK2019: unresolved external symbol __imp__TranslateMessage@4 referenced in function _WinMain@16
WinMain.obj : error LNK2019: unresolved external symbol __imp__DispatchMessageW@4 referenced in function _WinMain@16
WinMain.obj : error LNK2019: unresolved external symbol __imp__PeekMessageW@20 referenced in function _WinMain@16
WinMain.obj : error LNK2019: unresolved external symbol __imp__DefWindowProcA@16 referenced in function "long __stdcall MainWndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?MainWndProc@@YGJPAUHWND__@@IIJ@Z)
WinMain.obj : error LNK2019: unresolved external symbol __imp__PostQuitMessage@4 referenced in function "long __stdcall MainWndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?MainWndProc@@YGJPAUHWND__@@IIJ@Z)
WinMain.obj : error LNK2019: unresolved external symbol __imp__RegisterClassExW@4 referenced in function _WinMain@16
WinMain.obj : error LNK2019: unresolved external symbol __imp__CreateWindowExW@48 referenced in function _WinMain@16
WinMain.obj : error LNK2019: unresolved external symbol __imp__ShowWindow@8 referenced in function _WinMain@16
C:\source\StarTrekArmada\src\Output\NewArmada.exe : fatal error LNK1120: 8 unresolved externals
Build finished with error(s).
The program in question is just the basics to open a blank window, a Hello World in WinMain() so to speak. I can run The Code fine in Visual Studio 2022, and it does exactly what I expect, opens a blank window that I can move around and close. I note in VS I have go into the Project Properties, Linker options and set the Subsystem to Windows (/SUBSYSTEM:WINDOWS) for this, and I am assuming that connects the project to the Win32 APIs, however I can't seem to figure out how to manually do this via Command Line in VS Code, and I can't find any relevant answers anywhere online.
My Configuration for VS is fairly simple:
Tasks.json
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "Build with Microsoft (R) MSVC C/C++ Version 19.35.32217.1 for x86",
"command": "cl.exe",
"args": [
"/Zi",
"/MT",
"/MTd",
"/O2",
"/EHsc",
"/nologo",
"/std:c++20",
"/Fe${fileDirname}/Output/NewArmada.exe",
"${workspaceFolder}/src/*.cpp"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$msCompile"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "compiler: cl.exe"
}
]
}
c_cpp_properties.json
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/src/include/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.22000.0",
"compilerPath": "cl.exe",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "windows-msvc-x64"
}
],
"version": 4
}
I am using Microsoft's MSVC toolchain and the cl compiler. Is my issue actually the link settings and if it is, what commands do I need to set it correctly for Windows Desktop Development? I am Developing on Windows 11 Pro 64-bit I have VS 2022 Installed with the Desktop C++ Development Workload installed (Including Windows 11 SDK)
The Code:
//
// Main entry point to the program.
//
#include <windows.h>
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
int APIENTRY WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR cmdLine,
_In_ int cmdShow
)
{
const wchar_t* pClassName = L"Test Class Name";
WNDCLASSEXW wc = { 0 };
wc.cbSize = sizeof(wc);
wc.style = CS_OWNDC;
wc.lpfnWndProc = MainWndProc; // WindProc Not Yet Define
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = nullptr;
wc.hCursor = nullptr;
wc.hbrBackground = nullptr;
wc.lpszMenuName = nullptr;
wc.lpszClassName = pClassName; // Must be prefixed with "L" because Microsoft
wc.hIconSm = nullptr;
// Register Window Class
RegisterClassExW(&wc);
HWND hwnd = CreateWindowExW(
0,
pClassName,
L"Test Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
nullptr,
nullptr,
hInstance,
nullptr
);
if(hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, SW_SHOW);
while(true)
{
MSG msg;
if (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
break;
}
else
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
}
return 1;
}
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
// If we reach here, we have nothing left we wish to do, so let
// Windows handle it.
return DefWindowProc(hWnd, msg, wParam, lParam);
}