How does one gets started with Winforms style applications on Win32? - c++

A bit of background: I'm a C++ programmer mostly, but the only GUI stuff I've ever done was on top of .NET's WinForms platform. I'm completely new to Windows GUI programming, and despite Petzold's excellent book, I'm extremely confused.
Namely, it seems that most every reference on getting started with Win32 is all about drawing lines and curves and things -- a topic about which (at least at present time) I couldn't care less.
I need a checked list box, a splitter, and a textbox -- something that would take less than 10 minutes to do in Winforms land. It has been recommended to me to use the WTL library, which provides an implementation of all three of these controls -- but I keep getting hung up on simple things, such as getting the controls to use the right font, and getting High DPI working correctly. I've spent two days on this, and I can't help but think there has to be a better reference for these kinds of things than I've been able to find. Petzold's book is good, but it hasn't been updated since Windows 95 days, and there's been a LOT changed w.r.t. how applications should be correctly developed since it was published.
I guess what I'm looking for is a modern Petzold book. Where can I find such a resource, if any?

First up, there is virtually no documentation (that I could ever find) explaining how to use WTL. It seems to be a library by experts, for experts.
Your choices then are: Using the MFC app wizard to create an application, or going the Win32 API route. The Win32 API itself is a C API, MFC is a C++ wrapper around the C Win32 API, with the addition of a document-view application model.
However, instead of creating your controls from code: The closest analog the native Windows API has to a "WinForm" is a dialog box. Dialogs are layed out in resource files that are embedded during linking into the EXE or DLL you are developing. The dialog resource takes a font setting that is automatically applied to all controls on the dialog, and dialogs are layed out in terms of dialog units, not pixels, allowing them to automatically scale relative to the font face, and dpi setting on the users system.
If you create a dialog resource, and add it to a simple application, it need look no more complicated than this to get the dialog up onto the screen, and close in response to a click of the OK button.
#include <windows.h>
#include "resource.h"
BOOL CALLBACK MyDialogProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg){
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam){
case IDOK:
EndDialog(hwnd,wParam);
}
return TRUE;
}
return FALSE;
}
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hNull,LPCTSTR strCmdLine,int nCmdShow)
{
return DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,&DialogProc,0l);
}

There are definitely better ways. For starters, todays Windows apps are expected to have some sophisticated and cool features. If you plan to implement all these from scratch, you'll be spending a lot of time on your project.
Personally, I use MFC. Other choices are valid, but I would really question not using anything library like that at all. Especially when you are running into the types of problems you are.
Can you place these on a dialog box, or are you doing something unusual in a regular window? Normally, most controls are created by plopping them on a dialog designer. No messing with the font required.
Can you step through what you are trying to do and the problems you are seeing?

The Win32 API is aggravatingly hard to use directly, so don't. Most people use some GUI framework. I try to give my personal opinions about more popular choices:
WTL. It is bit too thin layer on Win32 API and has
not been updated much for a decade.
You will face Win32 API itself soon
enough if you try to do something
above simple stock examples with it. Bonus
is that it is extremely quick
compared to competition.
MFC.
Since VS 2008 SP1 MFC is allowing you
to make relatively modern-looking
GUI. If you can live with its strange
coding conventions and heavy macro
usage then it is livable. It is supported by VS IDE but far weaker than WinForms are.
WxWidgets. Initially felt a bit like
MFC that is additionally made
portable. It has become lot better
after people have started to use it
in Python as well.
QT. It is most
flexible and powerful of them.
Unfortunately it has started long
time ago so has some legacy
strangeness in it. It is slow at
places and produces big executables.
Best is to use it as well-isolated
GUI layer and not to mix heavy usage
of STL and boost into that layer.

Related

How should a Windows application with custom controls be drawn with Direct2D?

I would like to create a Windows application (for Windows 10) using the C++ and the Windows API. I already have some basic knowledge of using the built-in windows controls to create a basic application, but would now like to expand into custom controls . Since I have no need for my application to be compatible with anything but Windows 10, and would like to use a reliable API which supports transparency and anti-aliasing but is also fast enough to render a GUI, I have chosen to use Direct2D.
The MSDN documentation says:
'Your application should create render targets once'
Bearing this in mind, should each child window use one ID2D1HwndRenderTarget which renders only to the parent window (and doesn't respond to the child windows' WM_PAINT messages), or should there be a single ID2D1DCRenderTarget which would draw to each control using the device context from the WM_PAINT message (using bindDC() - although I would still like to be able to use transparency, and am not interested in GDI interoperability)? Should I even be using Direct2D at all?
I would like to use the Windows API, so a solution involving QT or MFC wouldn't work. I haven't got a specific application in mind, but would eventually like to create a simple library that would enable me to quickly produce GUI applications that have a custom look.
I have spent hours scouring the web for answers, but have found nothing conclusive. MSDN itself seems particularly unhelpful, it just teaches you to draw an ellipse and stops there. Please forgive me if I have accidentally broken the rules of asking questions - as you can probably tell I am new to Stack Overflow - and if any other information is needed, I will of course include it (I am using C++ with Visual Studio Community 2019).

Questions about C++ GUI project types and controls

I like C++, and I have used GUI many times in C#, but this time I would like to make a GUI in C++. I already know the basics of the Win32 API, such as creating a window, resource scripts, commands and processing of commands, and the basics of some controls.
 
But what I would like to know, is how to choose between pure Win32 API or MFC to make applications with sidebars that can be disconnected and connected from the window just by clicking and pulling, as the image below:
And the other type of control I'd like to know, is what kind of list is this in red in the image below? In the bottom circled, I know it's a mix of tree view with that kind of list. I thought it was a table control or similar, but it is not.
Anyway, I must continue studying pure Win32 API, or should I jump directly to MFC? I do not intend to use .NET or C#, only pure C++ with some libs.
You can also take a look at more modern C++ gui frameworks, like Qt.
If you want to learn more about Windows, you can use either Winapi or MFC. //MFC is just a pretty thin (and oop) layer over Winapi.
QBittorrent is using Qt framework, so those are most likely a QListWidget/QListView and QTreeWidget/QTreeView.

Skin a dialog box

I am writing a C++ application and I have a Login Box that's shown in a regular Dialog Box Frame. I see that some people can SKIN the entire dialog box and makes it look really nice. I was wondering if anyone can give me some pointers as to how to do that.
I'd need more details to give you a good answer.
The answer very much depends on which OS you're using and how you're programming your GUI (for example on Windows - plain Win32, MFC, ATL, Qt, Windows Forms, WPF etc etc).
If you're just using the Windows API here's a link to get you started.
http://www.codeproject.com/KB/dialog/skinstyle.aspx
Beware: custom skinning dialog boxes can be a very large task if you want to customise the look of every control as you end up writing very complicated custom controls.
Alternatively do you just want to make sure that your dialogs appear with Windows XP visual style rather than pre-XP style? This will require changes to your application to use the new common controls and visual style. Note that this changes the behaviour of some Windows APIs and can potentially have side effects (see ISOLATION_AWARE_ENABLED).

Custom Windows GUI library

I always wondered how software such as iTunes, Winamp etc is able to create its own UI.
How is this accomplished under the Windows platform? Is there any code on the web explaining how one would create their own custom GUI?
WinAmp doesn't usually supply its own GUI at all -- it delegates that to a "skin". You can download dozens of examples and unless memory fails me particularly badly, documentation is pretty easily available as well.
From the looks of things, I'd guess iTunes uses some sort of translation layer to let what's basically written as a native Mac UI run on Windows (the same kind of thing that Apple recently decided was so evil that they're now forbidden on the iPhone and apparently the iPad).
Since saying anything that could possibly be construed as negative about Apple is often treated as heresy, I'll point to all the .xib files that are included with iTunes for Windows. An .XIB file (at least normally) is produced by Apple's Interface Builder to hold resources for OS/X programs, and compiled to a .NIB file prior to deployment. Windows doesn't normally use either .XIB or .NIB files at all, and it appears likely to me that Apple includes a compatibility layer to use them on Windows (though I've never spent any time looking to figure out what file it's stored in or anything like that).
Edit: (response to Mattias's latest comment). Rendering it is tedious but fairly straightforward. You basically take the input from the skin (for example) and create an owner draw control (e.g. a button) and render the button based on that input.
The easiest way to do this is to have fixed positions for your controls, and require the user to draw/include bitmaps for the background and controls. In this case, you just load the background bitmap and display it covering the entire client area of your application (and you'll probably use a borderless window, so that's all that shows). You'll specify all your controls as owner-drawn, and for each you'll load their bitmap and blit it to the screen for that control. Since there won't (usually) be a visible title bar, you'll often need to handle WM_NCHITTEST (or equivalent on other systems) to let the user drag the window around.
If you want to get a bit more complex, you can add things like allowing them to also specify a size and position for each control, as well as possibly specifying that some controls won't show up at all. Again, this isn't really terribly difficult to manage -- under Windows, for example, most controls are windows, and you can specify a size and position when you create a window. If the user loads a different skin at run-time, you can call MoveWindow to move/resize each control as needed.
I'm assuming that you mean creating a GUI application as opposed to a GUI framework.
There are lots of GUI frameworks available for Windows.
Some are
wxWidgets (www.wxwidgets.org)
Qt (http://qt.nokia.com/products)
And of course the venerable MFC framework (http://msdn.microsoft.com/en-us/library/d06h2x6e%28VS.90%29.aspx)
If you want a more complete list, look at the Wikipedia article for MFC (http://msdn.microsoft.com/en-us/library/d06h2x6e%28VS.90%29.aspx) and scroll to the bottom.
Each of these GUI frameworks is amply documented on the web.

Windows Subclassing in Borland C++ Builder

We're trying to convert a piece of C++ code written in MFC which uses the CWnd.SubclassWindow method, into Borland C++ Builder code. Does anyone know how to do subclassing (subclass with a TForm object) - we're completely stuck. Any pointers will be much appreciated! TIA!
Specifics:
We have an existing base class written in Borland C++ which inherits from TForm, which is used to give all forms that inherits from it a certain look and feel (it processes WM_NCPAINT and WM_NCHITTESTheavily, for example).
Now we'd like to use this code to give forms written in other languages (MSVC++/MFC and C# to be exact) the same look and feel.
Instead of rewriting all the code we thought that using windows subclassing would be a great idea. Then we could stuff all the existing and tested code into a DLL and then just call it with a hWnd and that window would automagically get the new look and feel.
Exactly why this is so impossible is really not up to me to say - I don't code in Borland C++ myself. I wrote a stub in MFC in just a few minutes to show the Borland C++ developers what I wanted and they have spent days trying to mimic the MFC CWnd::SubclassWindow method without success.
From what I understand, the problem is that when you do a "new TForm()", then a new window is automatically created before you have any chance to stop it. So replacing then WindowProc works BUT an unwanted TForm window is floating around on the screen to no use!!!!
I'll assume you mean VCL. You can set the WindowProc property of a TControl object to your own window procedure or another control's WindowProc.
EDIT: More answer, based on more specifics
To prevent new TForm from creating a window to float uselessly around the screen, you should just need to set its Visible property to false. Alternatively, you could override CreateParams to remove the WS_VISIBLE style from the window:
void __fastcall TBlahForm::CreateParams(TCreateParams &Params)
{
TForm::CreateParams(Params);
Params.Style&=~WS_VISIBLE;
}
//---------------------------------------------------------------------------
There'll still be an invisible window getting created, but as I understand the use case, this shouldn't be a big deal.
Overriding TCustomForm::CreateWnd is potentially another way of attacking the same problem.
My other suggestion would be to just port the code from BCB to VC++. If it's doing lots of mucking around with WM_NCPAINT and WM_NCHITTEST then it sounds an unlikely candidate to have lots of VCL-specific stuff in it - it's probably just banging straight on the Win32 API? If there's nothing VCL in there, compiling in VC++ should pretty much just magically work.
In any event: it's almost certainly possible. I have an app built with BCB5 (which predates WinXP) that through clever use of window hooks, subclassing and the like (most of which isn't my own) is still perfectly happy dealing with XP and even Aero (which isn't to say it isn't a pain to maintain). If that's possible, your application certainly should be. VCL follows a different paradigm to MFC, but it's nonetheless flexible.
Have a look at the Codegear Online Docs, which describes the WindowProc mechanism for subclassing.
C++Builder uses the underlying Delphi VCL, so searching for "Delphi Window subclassing" will be more fruitful than trying to find something specifically C++. C++Builder programmers have to at least be capable of reading Delphi code, even if they don't have to write any!