Entry point in Visual C++ 6.0 - c

I am working on a legacy program, the executable is coded in C using just the Windows API, with Visual C++ 6.0.
Since all default libraries are removed, I cannot use WinMain() as normal. How can I specify a new entry point, I cannot find the option anywhere. I know this is possible as I have done it on Visual Studio C++ 2010.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MessageBoxA(NULL,"Hello World!","info",0);
return 0;
}
Error.
LINK : error LNK2001: unresolved external symbol _WinMainCRTStartup
Release/calcy.exe : fatal error LNK1120: 1 unresolved externals

I found it just after posting the question. Add this below header files.
#pragma comment(linker, "/ENTRY:main")

Related

Issues running WinMain in C

Currently I'm having issues with WinMain in C (specifically in Visual Studio).
For instance...
#include <stdio.h>
#include <Windows.h>
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR lpCmdLine, INT nCmdShow)
{
return(0);
}
1>------ Build started: Project: GameB, Configuration: Debug x64 ------
1>LIBCMTD.lib(exe_main.obj) : error LNK2019: unresolved external symbol main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ)
1>E:\James\VisualStudio\CProjects\GameB\x64\Debug\GameB.exe : fatal error LNK1120: 1 unresolved externals
1>Done building project "GameB.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Just this basic set-up gives me an "inconsistent annotation for WinMain" warning. I have been searching for any help for 2 days and the the closest I come to an answer is people talking about WinMain in the context of C++. I have a feeling this is a problem with Visual Studio as I was originally just using VS Code and managed to get an app (one that generated a pop-up window) to compile and run.
You just set up your winmain wrong. This should work:
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow);
or
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR lpCmdLine, INT nCmdShow)
{
return 0;
}
Don't forget to #include <Windows.h> and change subsystem to windows.
To use the WinMain program entry point, you need to tell the linker to target the "Windows" subsystem, rather than building a console application. Otherwise, the linker will look for (and fail to find) the standard main entry point for C programs.
In the Solution Explorer, right-click on your project and select "Properties". Then navigate to the "Linker -> System" page and select "Windows (/SUBSYSTEM:WINDOWS)" as the target:
On your "inconsistent annotation" warning, see this Q/A: Inconsistent annotation for 'WinMain'
Also, as noted in the answer by SNO, you should add the WINAPI attribute to your WinMain function.
You need to set subsystem from Console to Windows in settings, by right clicking your project in the solution explorer, selecting properties, and going to Linker->System and setting SubSystem to Windows(/SUBSYSTEM:WINDOWS).

Getting screen resolution in C, w/o "windows.h"

Just working on a small project using SDL2...
System info: Windows
App info: using C (pure C, no c++), mingw-x64 & SDL2.
Now;
Firstly, SDL.h requires the main function to be renamed as WinMain.
On the other hand, when getting the screen resolution, I tended to use the GetSystemMetrics function, which requires windows.h to be included in the pre-processor section and at this point, WinMain in my code conflicts with WinMain declared previously in winbase.h. When I'm using both (SDL.h and windows.h), compiler responds:
previous declaration of 'WinMain' was here: int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);
That's because, WinMain is declared somewhere in the winbase.h, which is auto-included via windows.h.
Is there a way to get the screen resolution w/o using GetSystemMetrics / windows.h? Any other ideas?
Ok! I've realized what I was doing wrong...
For the linking phase, I was using the following libraries and the linker was complaining about the WinMain function not to be found.
-lSDL2main
-lSDL2
Then I added the mingw32 library as shown below and the problem got solved (the order of the libraries does matter I think).
-lmingw32
-lSDL2main
-lSDL2

INITCOMMONCONTROLSEX was not declared in this scope

When I compile
#include<windows.h>
#include <commctrl.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
INITCOMMONCONTROLSEX ex;
return 0;
}
with
g++ 1.cpp -w -g -lgdi32 -lcomctl32 -o 1.exe
I get the error
1.cpp: In function 'int WinMain(HINSTANCE, HINSTANCE, LPSTR, int)':
1.cpp:8:2: error: 'INITCOMMONCONTROLSEX' was not declared in this scope
INITCOMMONCONTROLSEX ex;
^.
I suspect I am getting this error because in commctrl.h, following #if condition is not true.
#if (_WIN32_IE >= 0x0300)
typedef struct tagINITCOMMONCONTROLSEX {
DWORD dwSize;
DWORD dwICC;
} INITCOMMONCONTROLSEX,*LPINITCOMMONCONTROLSEX;
#endif
I tried compiling
#define _WIN32_IE 0x0300
#include<windows.h>
#include <commctrl.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
INITCOMMONCONTROLSEX ex;
return 0;
}
and this works fine, I don't get any errors. I looked up MSDN but there's nothing written about adding #define _WIN32_IE 0x0300 there.
Questions :
What is the purpose of _WIN32_IE ?
Do I really need to hardcode its value when MSDN writes nothing about doing so ?
The initial version of comctl32 shipped with Windows 95/Windows NT. From then on each release up to Windows 7 got a new updated version but these new versions first shipped as part of Internet Explorer. Internet Explorer 3, 4, 5, 6 and 7 usually included new versions of comctl32, shlwapi and shell32.
This is mostly ancient history these days but you still need to declare which version of Windows and IE you are targeting to unlock certain features.
Adding #define _WIN32_IE 0x0300 to your code unlocks the features introduced in IE 3.0 and your program will only run on Windows 95 ORS 2 or later, Windows 95 RTM will need IE3 or 4 to be installed.
You don't care about Windows 95 (hopefully) but the same type of #if check applies to many other newer features as well and not all of them are correctly documented on MSDN because they probably assume that you are using a Visual Studio project that is less than 20 years old.
Unfortunately the minimum OS version listed on MSDN is wrong and cannot be trusted. Microsoft has removed 99% of the information about versions before 2000 and they seem to ignore anything before 2003/Vista these days.
What is the purpose of _WIN32_IE?
The extended common controls library shipped with Internet Explorer before it became a standard part of Windows. If you set the macros to tell the SDK which version of Windows you're targeting, then the SDK will probably set the IE version for you.
The fact that you had to do this for functionality this old suggests that you're using an old version of Visual Studio and/or the SDK. You might want to consider updating.
Note that, for these common controls, you probably also want to make sure you enable Windows Visual Styles.
Do I really need to hardcode its value when MSDN writes nothing about doing so?
You should set WINVER and _WIN32_WINNT per the MSDN guidelines. Depending on the version of Visual Studio you have, you might be able to set it with a project property. You can also do it with the /D option on the compiler command line, or in a header file that's included before any Windows headers. If you use a pre-compiled header, you could do it at the top of that file.

How can I avoid the Console while doing GUI with C?

Okay this is the sample code
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MessageBox(NULL, "A threat has been detected by Windows!!", "Warning!!", MB_OK);
return 0;
}
But whenever I compile this. It gives me a Message Box as ecpected but what I get more is the Command Prompt with it. I just don't want that ugly thing how can I modify or compile my code to get only the GUI ? I am using Code::Blocks IDE.
This is related to Code Blocks IDE, you have to change the type application in your project.
From the project properties, tab Build Targets, change the type console application to GUI application.
Check: http://forums.codeblocks.org/index.php?topic=12007.0

Hello World (C and C++) for WinCE application - Visual Studio 2008

I'm a beginner for Visual Studio 2008 (32-bit). The WinCE version I'm using is 7.0 Evaluation. I created a new project as,
New Project -> Platform Builder-> OS Design
Selected the BSP as,
BSP: Generic CEPC:x86
When the design template highlighted Consumer Media Device, I just clicked Finish.
The above selections are a must for me. Besides these, I created a subproject as a simple hello world application and added a line cout<<"Hello World"; (as they are by default cpp files). I also included iostream.
I got errors such as,
fatal error C1083: Cannot open include file: 'iostream': No such file or directory
As stated in this link, I checked out for libcmtd.lib and it is in the $(VCInstallDir)lib. It is also included in Tools | Options | Projects and Solutions | VC++ Directories | Show Directories For -> Library files.
Based on this link, I checked the precompiled header settings. I found the following there:
Precompiled Files : Yes
Precompiled Header File Name : StdAfx.pch
Precompiled Header Object File Name : StdAfx.obj
Precompiled Header Options : (blank)
Precompiled Header Source File Name : StdAfx.h
How do I disable this? In case if I disable this, won't I get any other problems for the other part of the project?
Update:
For a C program,
#include<stdio.h>
int main()
{
printf("\nHello World\n");
return 0;
}
I got the following errors,
error LNK2019: unresolved external symbol _WinMain referenced in function _WinMainCRTStartupHelper
fatal error LNK1120: 1 unresolved externals
fatal error U1077: 'D:\WINCE700\sdk\bin\i386\x86\link.EXE' : return code '0x460'
What may be the linking problem here also?
The C code that you wrote, will not work in a WinCE app. The entry point for your WinCE app is WinMain, not regular main.
All that iostream stuff is from the STL. From my own experience there are some differences in how the STL is actually implemented on WinCE versus on Windows Desktop. That will be the source of issues now and in the future. Here's an SO article discussing these problems.
Here is how you might do it in WinCE (code not actually tested)
#include "stdafx.h"
using namespace std;
#include <iostream>
int WINAPI WinMain (
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow)
{
cout << "hello world" << endl;
return 0;
}
A Windows Application and a WinCE application follows different rules and needs different libraries than a console (CRT) app. In your Visual Studio, create a default Win32 project and create a default console app. Then compare the project files between all three in a text compare tool. You'll see many differences. These differences include at least the following:
A different entry point -- WinMain, _WinMain, _tWinMain, etc
They enable use of the windows.h file and all the related apparatus
A different set of default .lib files you must link to
Despite all of this, WinCE apps get fun when you get into the GUI stuff. If I were you, I'd get out of this C++ stuff and get into the C# Compact Framework.
When you want to write a main(argc, argv) style program you must choose console application in the project wizard.
It's not possible to use cout or printf statements in these kind of WinCE applications as 010110110101 said.
Instead, for displaying text, we shall use DEBUGMSG or RETAILMSG based on the build mode.
DEBUGMSG(TRUE,(TEXT("Hello World")));
RETAILMSG(TRUE,(TEXT("Hello World")));
For example, DEBUGMSG won't work in Release mode. The syntax for these messages is in this link.

Resources