c++ use of winmain() - c++

I just started learning programming for windows in c++. I had this crazy image, that win32 programming is based on calling windows functions and sending parameters to and from them. Like, when you want to create window, you call some win32 function that handles windows GUI and say "Hi, please, create me new window, 100 x 100 px, with two buttons", and that GUI function says "Hi, no problem, when something happends, like user clicks one button, I will change this variable xy located in this location".
So, I thought that it will be very similiar to console programming. But the very first instruction surprised me. I always thought that every program executes main() function first. So, when I launch app, windows stores some parameters on top of stack and run that application. So I assumed that initializing main() is just a c++ way to tell the compiler where the first instruction should be.
But in win32 programming, there is function called WinMain() which starts first. So I am little confused. I thought it´s rule that compiler must have main() to start with, that main just defines where it starts, like some start point identifier.
So, please, why is there WinMain() function instead of main()? When I thought that C++ programming is as logical as assembler, it confuses me once again.

main() is as arbitrary an entry point as WinMain() is. The standard only requires a function named main for consistency. The entry point (whether it's main or WinMain) is actually called by a hidden function that is the real entry point. On some platforms that "real" entry point is called something like _start. It's that function that does all of the initial work like initializing globals, setting up the environment, etc., and then it calls main(). On Windows, that start function happens to call WinMain() if available.
Edit: check out this answer for a more detailed explanation.

To understand how Win32 application works requires additional effort compared to usual console application.
"I had this crazy image, that win32 programming is based on calling windows functions and sending parameters to and from them"
my hints ...
1 )True , but also windows message that are the beats of a Windows Application , some example include WM_CREATE, WM_MOUSExx , WM_KEYxx , WM_PAINT where xx can be DOWN UP and so on .
Messages are sent to your application by Windows itself , it is up to you to define a specific function to trap them (the "WindowFunc").
There are hundreds of messages, luckily is not necessary to understand all them at first .
2) Every widget you can imagine to create in your app is a "Window" , and you can create Windows by CreateWindow function .Each window will be identified by a 32 bit integer value the so called Window Handle (HWND)
3 There are so many different class of windows as you can imagine (mainwindow , clientarea , edit, button) both available from the system and also created by yourself...
Windows are different as they belong from different WindowClass ...
To define a WindowClass you have to fill a WNDCLASS c structure and call RegisterClass
A field in the struct is a pointer to the WindowFunc
4 The WindowFunc is a function that takes 4 input parameters (HWND,WM_XX,wParam,lParam)
That function will be called from the system as soon as something happens regarding that window (HWND)
said that let me rewrite your statement
"Like, when you want to create window, you call some win32 function that handles windows GUI and say "Hi, please, create me new window, 100 x 100 px, with two buttons", and that GUI function says "Hi, no problem, when something happends, like user clicks one button,
...I will send you a message to the windowFunc as the user click... please check for the messagetype by yourself and if it is the WM_MOUSEDOWN you was waiting for then change the value for xy
What else ? i suggest to look at some simple sample in the sdk to get confident on how a win 32 app flow is
cheers

It is just a convention for native Win32 programs. You can easily change it, the MSVC linker accepts the /ENTRY:main command line option to change the entry point name to "main". You will however also have to change the signature of the main() function, it takes different arguments:
int APIENTRY main(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// etc..
}
Which I guess was the point of giving it a different name 20 years ago.

You can check this article and another one from a microsoft developer. Briefly there're several reasons: the name are arbitrary, windows' WinMain required a different signature, and windows predates c++ standarization.

Related

How to Add a Window in ConsoleApplication Project C++

Hi i Want to Add Window(Gui) to my ConsoleApplication in C++
How to do this?? I need something called Hwnd? I tried to use it and it does not work for me
Basically what I want to do is a MessageBox that will be every time somewhere else on the screen .. but I realized that you have to do it with HWND.
I need Tutorial How to create windows with hwnd
I try:
HWND GetWindow(HWND hWnd, UINT uCmd);
Check if the following code meet your requirement:
#include <windows.h>
int main()
{
MessageBox(nullptr, TEXT("Hello World!"), TEXT("Message"), MB_TOPMOST);
}
It will like this:
You've used multiple tags, I have a winapi solution, not a winforms one.
You can use a std. MessageBox by calling the function, but they can't be „evolved“ into your custom windows for any reasonable „price“ so they can only notify user and ask simple yes/no questions. For „real“ windows, let's forget MessageBox.
The simplest custom window is a std. windows Dialog. It uses the pre-defined window class #32770, so you don't have to register your window class, create a message loop etc. The simplest way to open it is DialogBoxParam function. You must make a .rc dialog script (there are lots of visual editors), compile it with a resource compiler, link into your .exe and pass it's name as the parameter for DialogBoxParam.
Here's an example of a window inside a console application (C++ part only), using this DialogBoxParam call
DialogBoxParam(GetModuleHandle(NULL),"EXAMPLE",NULL,ExampleWindowFunction,NULL);
It's here: https://pastebin.com/Crkdy5FB
It also contains image drawing (you probably don't need it yet, it's left from another winapi example). Use it as a sandbox, you'll probably quickly understand how it works and what role the hWnd plays here.
I understand your problems. GUI got so overcomplicated so it's hard to understand what exactly you don't understand. It prevents from asking a good question.

Windows Form Automation in C++ using low level WinAPI Calls?

I am working on a project that is supposed to take a program written in C++ using Windows forms (a basic calculator taking two ints, an operator and has an equals button) and automates it using C++ and low level WinAPI calls.
I have been googling a bit, but most of the references I find on this are fairly old and I want to make sure I'm going in the right direction. I see OLE Automation but not sure if that's the right direction
What I do know:
I cannot use Reflection, any 3rd party library including Visual Studio's UI/Testing automation assemblies.
I assume whatever I use I will launch the application, get the window by it's title, get each element by the element name somehow, simulate a click, read the calculated value, etc. It's just getting there that is the problem
It sounds like you're familiar with the basics of window handles and such so I'll skip that part, but here are some pointers to help you get started:
To find the form's control windows - EnumChildWindows()
To send messages to each of those windows - SendMessage()
Finally, a list of the messages you can send to buttons - Button Messages (for your program check out the BM_CLICK message in particular)
You can find MSDN references for each of the other controls' messages by goggling "msdn edit control (etc.) messages".

WinAPI - how to organize lots of HWND objects?

As I push forward my first winapi UI, I find myself creating large, uncomfortable stacks of HWND variables in my WinMain file:
HWND foo;
HWND bar;
HWND baz;
HWND etc;
int WINAPI WinMain(...) {}
Of course, these variables are used in the functions in the rest of the file - the message loop, for example - so they must be accessible.
For my relatively small UI, I'll have something like 30 HWNDs piled up so they're in a visible scope. This makes me very suspicious that I'm doing it wrong.
Is this what should be happening, or is there a more practical way to organize this?
You have a few solutions, depending what your program is.
You can put all those handles in one or many containers like std::vector.
You can map them like chris suggests.
If your program gets big, you might want to organize them into logical units. For example, if 15 of those windows are for one half of your logic and the other 15 for another half (say controls inside tabs) then you might want to group those controls in some way (file, class, whatever is the most logical fit).
You only need one HWND in your main program, and that's for a main window.
The API doesn't require a single main window, but that's most common. And even when from a user point of view the application offers several apparently independent windows, it's a good idea to have a main window in the program (it can be invisible, but provide grouping).
The other windows are then either children of the main window (within it), or windows "owned" by the main window. In general. And in particular for a first ever Windows program. :-) So you don't need separate variables for these windows. Whenever a window should react to something, that's a message to the window, which means a call of one your functions with the relevant window handle as argument.
Every child window can have a unique integer ID, and that's one way to keep track of them.
But as you get ahead you will want to associate state with each window, and the easiest way to do that is to use the Windows "subclassing" API to associate a pointer with each window. Then you can route window procedure calls to a method on an associated C++ object. Where different messages can be routed further to different message handling methods, each with access to window's state (it's just this C++ object).

How to create a windows application in C++ showing just a TaskDialog

I need to create a windows application in C++ and it has to show just a TaskDialog (see http://msdn.microsoft.com/en-us/library/windows/desktop/bb760540(v=vs.85).aspx ). The TaskDialog should show a text passed as parameter to the command line.
I can make a "Win32 Console Application" and call TaskDialog but then I will see the black windows of the console.
I can make a "Windows Application" and just calling TaskDialog inside WinMain, is there any problem with this solution?
Any other idea?
I can make a "Windows Application" and just calling TaskDialog inside WinMain, is there any problem with this solution?
That is the way to implement such an app. There is no problem with it all. Of course you don't create a window explicitly in your code and you don't run a message loop. Just call TaskDialog.
The main point is that you don't want a console app because, as you have discovered, a console window is shown by default. There are two main subsystems, the console subsystem and the GUI subsystem. The latter is somewhat confusingly named. You are not compelled to show GUI in a GUI subsystem app. It's up to you whether or not you choose to do so. Really the choice comes down to whether or not you want a console. So the subsystems could be better named as console and non-console!
You have to create a empty windows application.
The entry point of a windows application is calles WinMain and looks like this:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
//Place your code here
}
This means your solution is correct. You just have to make sure that your application uses version 6 of Comctl32.dll. Otherwise TaskDialog will fail.

How do I write a console application in Windows that would minimize to the system tray?

I have a written a Visual C++ console application (i.e. subsystem:console) that prints useful diagnositic messages to the console.
However, I would like to keep the application minimized most of the time, and instead of minimizing to the taskbar, appear as a nice icon on the system tray. I would also like to restore the console when the system tray icon is clicked.
How should I change my program to do this?
This is going to be an ugly hack.
First, you have to retrieve the hWnd / hInstance of you console application. Right now, I can only come up with one way:
Create a Guid with CoCreateGuid()
Convert it to a string
Set the title of the console window to this guid with SetConsoleTitle()
Find the hWnd of the your window with the Guid as the tile with FindWindow()
And you can do it from the usual way from this point. See http://www.gidforums.com/t-9218.html for more info.
Don't forget the rename your console window to the original title once you're done.
As you can see, even though this is possible to do, it's a horrible and painful solution. Please don't do it. Please do not minimize console applications to the system tray. It is not something you are supposed to be able to do in the Windows API.
You might want to write a separate gui to function as a log reader. You will then find it much easier to make this minimize to the tray. It would also let you do some other stuff you might find useful, such as changing which level of logging messages are visible on the fly.
To learn the console's hWnd you have two choices:
On Windows 2000 or later you can use the GetConsoleWindow() function. Don't forget to define _WIN32_WINNT as 0x0500 or greater before including windows.h to have access to this function.
If you want to run your program on earlier Windows versions as well then you must use something like the GUID trick described above.
Probably your best bet is to create a "Message-only window" (a message queue without a visible window) to receive the Notification Area messages.
The answer with a GUID is completely ridiculous (no sense at all)
The Console hWnd is of course given by GetConsoleWindow() (!)