It is currently Sun Oct 21, 2018 9:29 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 26 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Mon Dec 18, 2017 4:51 pm 
Offline

Joined: Mon Jan 30, 2017 5:20 pm
Posts: 317
Location: Colorado USA
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.


Top
 Profile  
 
PostPosted: Mon Dec 18, 2017 5:39 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20681
Location: NE Indiana, USA (NTSC)
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.


Top
 Profile  
 
PostPosted: Mon Dec 18, 2017 5:55 pm 
Offline

Joined: Mon Jan 30, 2017 5:20 pm
Posts: 317
Location: Colorado USA
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?


Top
 Profile  
 
PostPosted: Mon Dec 18, 2017 6:44 pm 
Offline

Joined: Thu Jun 04, 2009 9:07 am
Posts: 35
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/


Top
 Profile  
 
PostPosted: Mon Dec 18, 2017 6:51 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 4093
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!


Top
 Profile  
 
PostPosted: Mon Dec 18, 2017 7:39 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1439
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.


Top
 Profile  
 
PostPosted: Mon Dec 18, 2017 8:45 pm 
Offline

Joined: Mon Apr 07, 2008 6:08 pm
Posts: 331
Location: Missouri
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


Top
 Profile  
 
PostPosted: Mon Dec 18, 2017 9:38 pm 
Offline

Joined: Sun Mar 27, 2011 10:49 am
Posts: 266
Location: Seattle
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.


Top
 Profile  
 
PostPosted: Mon Dec 18, 2017 9:48 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 4093
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!


Top
 Profile  
 
PostPosted: Tue Dec 19, 2017 10:56 am 
Offline

Joined: Mon Jan 30, 2017 5:20 pm
Posts: 317
Location: Colorado USA
I'll show you what happens when when you create a Win32 project in Visual Studio 2015
Code:
#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


Top
 Profile  
 
PostPosted: Tue Dec 19, 2017 11:26 am 
Offline

Joined: Sun Mar 27, 2011 10:49 am
Posts: 266
Location: Seattle
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:
typedef HANDLE HINSTANCE;

and that there's a line in WinNT.h that reads
Code:
typedef PVOID HANDLE;

and finally, another line in WinNT.h that reads
Code:
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:
Quote:
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:

Quote:
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++.


Top
 Profile  
 
PostPosted: Tue Dec 19, 2017 11:41 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 4093
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!


Top
 Profile  
 
PostPosted: Tue Dec 19, 2017 12:50 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20681
Location: NE Indiana, USA (NTSC)
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.


Top
 Profile  
 
PostPosted: Tue Dec 19, 2017 1:52 pm 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1708
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:
#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:
.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.

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Wed Dec 20, 2017 2:42 pm 
Offline

Joined: Mon Jan 30, 2017 5:20 pm
Posts: 317
Location: Colorado USA
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?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 26 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group