Can you write windows app in regular C++?

You can talk about almost anything that you want to on this board.

Moderator: Moderators

DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Can you write windows app in regular C++?

Post by DementedPurple »

I don't want to use visual C++. I read an entire tutorial on C++ only for visual "C++" in making a Win32 app in Visual Studio to barely be the same language at all. Practically none of the instructions in the WinAPI template are even native C++. Can I do it in perhaps regular C++? I don't want to worry about learning all of these scarcely documented instructions and just use C++. I doubt I got any of the terminology right, and who could blame me? it's so unnecessarily complicated and details are scarce, and when you do find them, they aren't much help for a noob.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Can you write windows app in regular C++?

Post by tepples »

Every platform will have different means of input and output, with different functions, classes, or templates that access it. The standard I/O in <cstdio> and <iostream> is one platform. GTK+ is another, as is Win32. It's like 6502 assembly: the ports that you write to display a sprite on a Commodore 64 differ from those on an NES, despite both using a 6502 core.

And if you think Win32 is "scarcely documented", have you looked at MSDN? But if you use gtkmm (which is also documented), you can target both Windows and GNU/Linux.
DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Re: Can you write windows app in regular C++?

Post by DementedPurple »

tepples wrote: And if you think Win32 is "scarcely documented", have you looked at MSDN? But if you use (which is ), you can target both Windows and GNU/Linux
MSDN just assumes you already know what all these things that aren't in native C++ already do, and when looking up what they do just make things more sophisticated. It's not that I lack understanding of C++, I've read entire tutorials, so I understand it pretty well. It just adds so much stuff that it makes it like an entire new language rather then C++. Why can't it be more like Arduino? Arduino is super simple to program, I've gotten an understanding of it in less then a week, same with just C++, why does it have to be so sophisticated?
Hangin10
Posts: 37
Joined: Thu Jun 04, 2009 9:07 am

Re: Can you write windows app in regular C++?

Post by Hangin10 »

Visual C++ for Windows Store/UWP apps is currently stuck using their proprietary C++/CX language that auto generates opaque regular C++ behind the scenes. They do plan to convert over to a new C++/Winrt "projection" that allows for native C++20 (so much co_await!). There's a github page here with project templates and examples: https://github.com/Microsoft/cppwinrt/
User avatar
Dwedit
Posts: 4922
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Can you write windows app in regular C++?

Post by Dwedit »

There is no distinction between "regular" C++ and "visual" C++.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
Quietust
Posts: 1918
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Can you write windows app in regular C++?

Post by Quietust »

The "Visual" in "Visual C++" refers only to the development environment, just like there's also "Borland C++" and other similar ones.

Strictly speaking, you don't even need C++ to write a Windows application - plain C will work just fine for the basic APIs necessary to write an NES emulator, even including DirectX for input/output.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
strat
Posts: 409
Joined: Mon Apr 07, 2008 6:08 pm
Location: Missouri

Re: Can you write windows app in regular C++?

Post by strat »

QT is another platform for making Windows apps in C++. Although there are QT hooks for other languages including Python.
http://doc.qt.io/qt-5/windows-support.html
adam_smasher
Posts: 271
Joined: Sun Mar 27, 2011 10:49 am
Location: Victoria, BC

Re: Can you write windows app in regular C++?

Post by adam_smasher »

DementedPurple wrote:MSDN just assumes you already know what all these things that aren't in native C++ already do, and when looking up what they do just make things more sophisticated.
Can you provide a specific example of something that's not "native C++" that's being used for Win32 programming and that's confusing you?
DementedPurple wrote:It's not that I lack understanding of C++, I've read entire tutorials, so I understand it pretty well...I've gotten an understanding of it in less then a week, same with just C++
Professional programmers familiar with similar languages can spend months studying C++ without getting a pretty good understanding of it - it's one of the most obnoxiously complicated languages in widespread use. Saying that your understanding of it comes from having "read entire tutorials" in "less than a week" doesn't exactly fill me with a lot of confidence. Sorry if this comes off as harsh, but I think you're trying to run when you don't even realize the difference between crawling and walking.
DementedPurple wrote:why does it have to be so sophisticated?
Because Win32 is a full-featured low-level GUI programming interface that's accrued over 30 years of backwards compatibility cruft, originally designed for a single-user cooperatively multitasked graphical shell with no memory protection that needed to be performant on ultra-slow 16-bit 8088 CPUs with low-colour unaccelerated CGA graphics. That Microsoft has managed to adapt it to a secure (yes) and modern, 64-bit multi-user preemptively multitasked OS as gracefully as they have is astonishing and quite honestly a feat without any real comparison anywhere in computing history, as far as I can recall. It's not surprising that it's a little inelegant.

Anyway. Yes, you can write a Win32 application in normal C or C++; here's an example. That site's great, by the way - if you're really invested in learning Win32 programming, try to grok just about everything on it.
User avatar
Dwedit
Posts: 4922
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Can you write windows app in regular C++?

Post by Dwedit »

adam_smasher wrote:Because Win32 is a full-featured low-level GUI programming interface that's accrued over 30 years of backwards compatibility cruft
I think you can still run Windows 1.0 programs on Windows 10 32-bit edition.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Re: Can you write windows app in regular C++?

Post by DementedPurple »

I'll show you what happens when when you create a Win32 project in Visual Studio 2015

Code: Select all

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;                                // current instance
WCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: Place code here.

    // Initialize global strings
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WIN32PROJECT3, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32PROJECT3));

    MSG msg;

    // Main message loop:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW 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(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT3));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_WIN32PROJECT3);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // Store instance handle in our global variable

   HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND  - process the application menu
//  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)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // Parse the menu selections:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: Add any drawing code that uses hdc here...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}
I mean you've got DefWindowProc, hInstance, wcex, and all sorts of sophisticated stuff that I don't understand. And when you look those things up, you just get a more complicated answer
adam_smasher
Posts: 271
Joined: Sun Mar 27, 2011 10:49 am
Location: Victoria, BC

Re: Can you write windows app in regular C++?

Post by adam_smasher »

Okay, but those things *are* native C++, they're just functions and types that come from the Win32 API.

This page here explains that there's literally a line in WinDef.h that reads

Code: Select all

typedef HANDLE HINSTANCE;
and that there's a line in WinNT.h that reads

Code: Select all

typedef PVOID HANDLE;
and finally, another line in WinNT.h that reads

Code: Select all

typedef void *PVOID;
So there you go - an HINSTANCE is just a void pointer. The reason why MS goes through the pains of defining all these constants is partially to make it more obvious just from the types what that pointer is supposed to represent, so that you're less likely to pass the wrong data to the wrong functions; and partially so that they can change the underlying implementation without forcing end users to change tons of their code - this is part of that whole astonishing backwards compatibility thing. They even allude to this on that page when they write:
HMODULE and HINSTANCE are the same today, but represented different things in 16-bit Windows.
DefWindowProc is short for "Default Window Procedure". Again, it's just a normal C function that Microsoft includes in their Win32 libraries. In Windows, every type of window ("Window Class", or "WndClass") has an associated function called a "Window Procedure" or "WndProc" that gets called with messages to respond to events, like when the user clicks on the window or whatever. Often you don't care about those events, but you can't just ignore them or Windows starts to worry that your program has crashed or is acting up; you need to acknowledge them. So the idea is that in your WndProc you pass any messages that you don't care about along to DefWindowProc to let the Win32 library handle the default processing. This is explained on MSDN:
Calls the default window procedure to provide default processing for any window messages that an application does not process. This function ensures that every message is processed. DefWindowProc is called with the same parameters received by the window procedure.
Anyway, there's no magic here. It's totally normal for C++ libraries to provide new types and functions, often hiding the details of how they're implemented. That's what abstraction is all about. There's no fundamental difference between, say, DefWindowProc() and printf() (except that one only exists on Windows of course). And as long as you have the right headers and libraries set up, you can totally compile this code using GCC or Clang instead of Visual Studio - it's all native C++.
User avatar
Dwedit
Posts: 4922
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Can you write windows app in regular C++?

Post by Dwedit »

HINSTANCE also happens to be the address of your program code. So if you were to look around in memory there, you'd see x86 instruction bytes.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Can you write windows app in regular C++?

Post by tepples »

adam_smasher wrote:And as long as you have the right headers and libraries set up, you can totally compile this code using GCC or Clang instead of Visual Studio - it's all native C++.
Case in point: MinGW is a version of GCC designed to target the Windows API.
User avatar
DRW
Posts: 2225
Joined: Sat Sep 07, 2013 2:59 pm

Re: Can you write windows app in regular C++?

Post by DRW »

To make it short: No, you cannot write a windows application with just regular standard C++. There isn't a GUI equivalent to "iostream" and all those other standard headers.
You cannot call a function std::createdlg() like you can call std::cout << "Hello".

Standard ISO C++ doesn't define any functions for windows and dialog boxes etc. since they are not platform-independent.

That's why you need to use the WinAPI or a wrapper library.

The reason why a WinAPI application in Visual C++ looks so complicated is because it already includes everything that you need to create a window.

After all, you could also simply just do this:

Code: Select all

#include <windows.h>

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    MessageBox(NULL, "Hello", "Message", MB_OK);
}
But this wouldn't help anybody.
So, the Visual C++ template creates everything for you that you need for a standard window: Creating the window, a message loop, an event function etc.

But this has nothing to do with "regular C++" vs. "Visual C++".
Apart from the fact that a Windows program has WinMain instead of main, this is all pretty much standard C++: It uses types and a bunch of functions. The types are not part of the language, but can be found in the header file, just like you yourself could define types in header files, like typedef int MyCoolNumber;.

That template is like with NES programming in Assembly:
An IDE that creates an NES template for you would maybe fill the code files with a reset interrupt, an NMI interrupt, system initialization and a controller reading function.

And you might ask yourself: Why does regular Assembly work with LDA and STA while "NES Assembly" uses such complicated things like vectors and stuff?

Because "NES Assembly" isn't a language. You're simply looking at a bare-bones compilable Assembly program that properly initializes itself for use on the NES.

It's the same with that WinAPI program: This is simply a bare-bones program to create a window. The code is still standard C++, only that it uses a bunch of functions, structs and typedefs to actually get a window on the screen.

But those things are no more sophisticated than if you wrote an Assembly macro:

Code: Select all

.macro ADD_3 variable
    INC variable
    INC variable
    INC variable
.endmacro
And someone who saw this macro used in your code (ADD_3 Status) would ask: "What kind of sophisticated stuff is this? I thought all commands in Assembly consist only of three letters."

If you want to understand what your code template does, you can check this tutorial:
http://www.winprog.org/tutorial

If WinAPI is too complicated for you and you want to be able to create windows right away as you would do in C#, you can look for GUI libraries: MFC was Microsoft's own wrapper library. Borland C++ used its own as well. And then there are compiler-independent libraries like Qt etc.
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Re: Can you write windows app in regular C++?

Post by DementedPurple »

Unrelated question while we're talking about C++, I would like to know what classes and objects are, I understand that they're kind of like folders as in the class is the folder and the objects are the files in a folder, but I have a hard time seeing any use for them. Could you perhaps give an example of what they are used for?
Post Reply