Нужно было создать маленькое приложение, которое загружает и обновляет файл, при этом отображает ход процесса.
Использую RAD Studio 10.4, по обычаю использую File > New > Other … > C++Builder Projects > Console Application
Пишу код для создания окошка ( https://learn.microsoft.com/ru-ru/cpp/windows/walkthrough-creating-windows-desktop-applications-cpp?view=msvc-170 ):
#include <windows.h>
#include <windowsx.h>
#define SimWnd_DefProc DefWindowProc
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
BOOL Register(HINSTANCE hInstance);
HWND Create(HINSTANCE hInstance, int nCmdShow);
static char szAppName[] = "SimpleWnd";
static HWND hMainWindow;
void SimWnd_OnDestroy(HWND hwnd);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) {
MSG Msg;
if (!Register(hInstance))
return FALSE;
if (!Create(hInstance, nCmdShow))
return FALSE;
while (GetMessage(&Msg, NULL, 0, 0)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
BOOL Register(HINSTANCE hInstance) {
WNDCLASS WndClass;
WndClass.style = CS_HREDRAW | CS_VREDRAW;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = szAppName;
return (RegisterClass(&WndClass) != 0);
}
HWND Create(HINSTANCE hInstance, int nCmdShow) {
HWND hwnd = CreateWindow(szAppName, szAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (hwnd == NULL)
return FALSE;
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
return hwnd;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
switch (Message) {
HANDLE_MSG(hwnd, WM_DESTROY, SimWnd_OnDestroy);
default:
return SimWnd_DefProc(hwnd, Message, wParam, lParam);
}
}
void SimWnd_OnDestroy(HWND hwnd) {
PostQuitMessage(0);
}
и получаю: [ilink32 Error] Error: Unresolved external '_main' referenced from C:\PROGRAM FILES (X86)\EMBARCADERO\STUDIO\21.0\LIB\WIN32C\RELEASE\C0X32.OBJ
Понятно, что линкер ищет точку входа main()
вместо WinMain()
, вот только где это настраивается…
Оказалось что есть старый «баг» не дающий в визарде создания проекта выбрать НЕ консольное приложение»:
Для того чтобы переключить данный чек бокс, нужно воспользоваться редактором реестра и внести изменения в ключ:
HKEY_CURRENT_USER\Software\Embarcadero\BDS\<version>\Repository\New Console Application
(REG_SZ) "ConsoleApp" = "True" or "False"
Или есть второй способ создания приложения с точкой входа WinMain()
— создать VCL Forms Application, удалить автоматически созданную форму и ненужный код в проекте.
https://stackoverflow.com/questions/29283438/create-win32-application-in-cbuilder-xe5
Пример минимального кода приложения для отображения MessageBox
#include <windows.h>
#include <tchar.h>
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpszCmdLine, int nCmdShow) {
MessageBox(0, _T("Hello world..."), _T("Hello world..."),
MB_ICONINFORMATION | MB_OK);
return 0;
}