Forum: PC-Programmierung Einstieg Windows-Programmierung (MSVS C++) zum Vergleich zu Qt


von Guy (Gast)


Lesenswert?

Ich bin in die Windowsprogrammierung reingerutscht, habe bislang aber 
nur ein bißchen mit Qt gearbeitet. Ich kann nichts dagegen sagen, kenne 
aber bislang nichts anderes (und bin kein Informatiker).
Deswegen wollte ich mir mal ein Video-Tutorial zum aktuellen, 
"offiziellen" Windows-GUI-Programmierungs-Weg ansehen, damit ich einen 
Überblick und einen Ansatz zum Vergleich habe - aber habe nicht wirklich 
was gefunden.
Evtl. kennt ja jemand was.

MFC, Windows Forms etc. - was ist da der aktuelle Stand?
Sollte man sich bei der Gelegenheit auch Alternativen zu C++ ansehen 
oder ist das alles neumodischer Kram?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Guy schrieb:
> MFC, Windows Forms etc. - was ist da der aktuelle Stand?

"Windows Forms" ist nicht C++, sondern erfordert den .Net-Unterbau.

Natives C++ ist nur mit der MFC (oder anderen, nicht von MS stammenden 
GUI-Toolkits) möglich, und die MFC würde ich Anfängern in der 
Windows-Programmierung definitiv nicht empfehlen.

Wenn man nicht darauf festgelegt ist, natives C++ zu verwenden, dann 
kann man sich auch mit .Net beschäftigen (von mir nicht liebevoll 
".Net-Geraffel" genannt), aber damit gräbt man sich halt auch eine 
gewisse Abhängigkeitengrube.

Ich würde ein plattformunabhängiges GUI-Toolkit nutzen, wie eben das von 
Dir erwähnte Qt oder wxWidgets.

von HutHut (Gast)


Lesenswert?

Wie der Vorredner schon sagte, wenn du nicht zwanghaft an die MFC 
gebunden bist dann nutzen es aus und suche dir etwas anderes. MFC ist 
die Ausgeburt des Bösen.

von Guy (Gast)


Lesenswert?

Hi und Danke.
Also ist der aktuelle Weg immer noch die MFC? Dann suche ich noch mal 
nach einer Einführung.
Plattformunabhängigkeit muss nicht sein, es wird eh Windows.

von Sharping (Gast)


Lesenswert?

Für GUI Programmierung ist C++ aber auch nicht mehr ganz Zeitgemäß. Da 
solltest du dir überlegen, ob du dir nicht den Luxus gönnen könntest, 
auf etwas high-leveligeres umzusteigen (z.B. C#). Da kommst du u.U. 
deutlich schneller und einfacher zum Ziel...

von Sebastian L. (Gast)


Lesenswert?

Also der aller neuste schrei sind WinRT Anwendungen für Win 8, sowas 
willst du sicher nicht.

WPF ist dann das nächst neuerste. Das ist aber nicht ganz so einfach für 
Einsteiger.

Winforms sind eigentlich schon "ewig alt" aber die am meisten 
verbreiteste Form der Anwendungsentwicklung im Windowsbereich.

MFC wird nur noch für sehr wenige alte Projekte verwendet und für neue 
Projekte eher ungeeignet.

Ich rate dir zu Winforms

von Philip (Gast)


Lesenswert?

Also ich persönlich will seitdem ich Qt kenne mit nichts anderem mehr 
arbeiten:-) Verstehe nicht, warum man da freiwillig auf MFC oder 
Winforms wechseln sollte, wenn einem nicht vorgeschrieben wird.

von Marco M. (marco_m)


Lesenswert?

MFC ist echte Qualitätssoftware, solide wie ein Fels. Z.B.  OBJCORE.CPP:
1
void CObject::AssertValid() const
2
{
3
  ASSERT(this != NULL);
4
}

und wie ist AssertValid deklariert? In AFX.H:
1
virtual void AssertValid() const;

O_o

von Sharping (Gast)


Lesenswert?

Philip schrieb:
> Verstehe nicht, warum man da freiwillig auf MFC oder
> Winforms wechseln sollte,

Weil man damit für gewöhnlich deutlich schneller eine Anwendung 
hochziehen kann.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Marco M. schrieb:
> MFC ist echte Qualitätssoftware, solide wie ein Fels. Z.B.  OBJCORE.CPP:

Und was genau willst Du da als Problem ansehen?

von Marco M. (marco_m)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Marco M. schrieb:
>> MFC ist echte Qualitätssoftware, solide wie ein Fels. Z.B.  OBJCORE.CPP:
>
> Und was genau willst Du da als Problem ansehen?

Eine virtuelle Memberfunktion testet ob this!=NULL ist?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Erklärs mir: Warum soll sie das nicht dürfen?

von Marco M. (marco_m)


Lesenswert?

Das ist aus mehreren Gründen Quatsch:

In praktisch jeder Implementation muss der Code den this-Pointer 
dereferenzieren, damit der an die vtable für den virtual call kommt. Das 
geht natürlich nicht, wenn this NULL ist. Also ist der Test Unfug.

Wenn der Compiler aber immerhin garantieren sollte, daß  nicht 
virtuelle Methoden mit this==NULL aufgerufen werden können (und der Test 
nicht etwa wegoptimiert wird), dann funktioniert es nicht, sobald 
Multiple Inheritance ins Spiel kommt. Wenn ich also also z.B:

class MyGadget: public MyBase, public CWnd { ... };

mache und MyBase nicht leer ist, dann haben MyGadget NULL Pointer einen 
von NULL verschiedenen Wert, wenn man eine Methode aus CWnd aufruft. So 
ein Test ist natürlich für die Katz.

Solche this==NULL Tests lassen mich immer aufhorchen, weil die oftmals 
ein Zeichen von Voodoo-Programmierung sind. Da werden böse NULL Zeiger 
mit wirkungslosen Tests beschworen, weil der Entwickler keinen Schimmer 
hat, was er da überhaupt macht. Diese Implementation von AssertValid() 
ist übrigens mindestens seit der in Visual Studio 6.0 mitgelieferten 
Version von MFC drin und auch in der Version von Visual Studio 2010 
unverändert drin und ist demzufolge in zwölf Jahren nicht angerührt 
worden.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Marco M. schrieb:
> Das geht natürlich nicht, wenn this NULL ist.

OK, akzeptiert.

von Sven P. (Gast)


Lesenswert?

Ich 'versuche' das zu verfolgen, seit ich damals(tm) mit VB6.0 aufgehört 
hab. Seitdem ist Windows irgendwie etliche Male in Sackgassen gerannt. 
MFC/WinAPI war schon immer und ist weiterhin einfach nur eine Zumutung. 
Mach irgendwie einen Bogen drum wenn du kannst, alles ist besser, 
wirklich.

Ansonsten fliegt für mich schonmal alles raus, wo die Oberfläche 
irgendwie in festen Maßen gebaut wird ('Knopf 150 pixel breit'), sprich 
alles ohne gescheite Layout-Manager. Denn ohne Layout-Manager geht es 
spätestens bei mehrsprachigen Anwendungen garantiert in die Hose. Das 
ist an sich schon ein Kriterium, anhand dessen du etliche Techniken 
aussortieren kannst.


Marco M. schrieb:
>
1
> virtual void AssertValid() const;
2
>
Ich stehe ja zugegebenermaßen nicht sonderlich feste in C++: Aber wie 
ruft man denn eine nicht-statische Methode eines Objekts auf, ohne ein 
Objekt zu haben?

von Εrnst B. (ernst)


Lesenswert?

Sven P. schrieb:
> ruft man denn eine nicht-statische Methode eines Objekts auf, ohne ein
> Objekt zu haben?

Mit casts ;)
1
(CObject *)(NULL)->assertValid(); // assertion fails.

Im normalen Programmlauf: Objekt gelöscht, danach Pointer auf NULL 
gesetzt, später trotzdem weiterverwendet.
d.H. Wenn du immer "delete obj; obj=NULL;" schreibts, dann macht 
dieser Check evtl. auch Sinn.

von Sven P. (Gast)


Lesenswert?

Εrnst B✶ schrieb:
> Sven P. schrieb:
>> ruft man denn eine nicht-statische Methode eines Objekts auf, ohne ein
>> Objekt zu haben?
>
> Mit casts ;)
Aha, das fällt also in die gleiche Schublade wie
1
uint8_t i;
2
if (i > 255)
3
        i = 255;

Dachte ich mir doch.

von Marco M. (marco_m)


Lesenswert?

Εrnst B✶ schrieb:

> Im normalen Programmlauf: Objekt gelöscht, danach Pointer auf NULL
> gesetzt, später trotzdem weiterverwendet.
> d.H. Wenn du immer "delete obj; obj=NULL;" schreibts, dann macht
> dieser Check evtl. auch Sinn.

Nicht wenn der Check eine virtuelle Methode ist.

von Εrnst B. (ernst)


Lesenswert?

Marco M. schrieb:
> Nicht wenn der Check eine virtuelle Methode ist.

Stimmt natürlich, soweit hab ich nicht mitgedacht...

Der Compiler könnte zwar den VTable-Lookup einsparen, wenn die Klasse 
zur Compile-Time bekannt ist, aber da wirds dann schon sehr Akademisch, 
und "undefined behavior" bleibts so oder so...

von Karl H. (kbuchegg)


Lesenswert?

Marco M. schrieb:
> Εrnst B✶ schrieb:
>
>> Im normalen Programmlauf: Objekt gelöscht, danach Pointer auf NULL
>> gesetzt, später trotzdem weiterverwendet.
>> d.H. Wenn du immer "delete obj; obj=NULL;" schreibts, dann macht
>> dieser Check evtl. auch Sinn.
>
> Nicht wenn der Check eine virtuelle Methode ist.


OK. Sagen wir mal so: Der Test ist so gesehen reichlich sinnlos, weil er 
im Grunde nichts bewirkt oder abfängt.

Allerdings haben die Mannen bei MS in der MFC noch ganz andere logische 
Böcke geschossen, die tatsächlich Schwachsinn sind.

Beispiel?
1
BOOL CSplitterWnd::OnMouseWheel(UINT fFlags, short zDelta, CPoint point)
2
{
3
  BOOL bRetVal = FALSE;
4
  int row;
5
  int col;
6
7
  BOOL bHasVert = FALSE;
8
9
  // determine if any of the panes have a vertical scroll bar
10
  for (row = 0; row < m_nRows; row++)
11
  {
12
    for (col = 0; col < m_nCols; col++)
13
    {
14
      CWnd* pPane = GetPane(row, col);
15
      CScrollView* pView = DYNAMIC_DOWNCAST(CScrollView, pPane);
16
      if (pView != NULL)
17
      {
18
        CScrollBar* pBar = pView->GetScrollBarCtrl(SB_VERT);
19
        if (pBar != NULL && pBar->IsWindowEnabled())
20
        {
21
          bHasVert = TRUE;
22
          break;
23
        }
24
      }
25
    }
26
    if (bHasVert)
27
      break;
28
  }    
29
30
  // find panes in the splitter that have scroll bars
31
  // and have them do their scrolling
32
  for (row = 0; row < m_nRows; row++)
33
  {
34
    for (col = 0; col < m_nCols; col++)
35
    {
36
      // only do the scrolling if the window is-a CScrollView
37
      CWnd* pPane = GetPane(row, col);
38
      CScrollView* pView = DYNAMIC_DOWNCAST(CScrollView, pPane);
39
      if (pView != NULL)
40
      {
41
        // prefer to scroll vertically if available
42
        CScrollBar* pBar = NULL;
43
        if (bHasVert)
44
          pBar = pView->GetScrollBarCtrl(SB_VERT);
45
        else
46
          pBar = pView->GetScrollBarCtrl(SB_HORZ);
47
        if (pBar == NULL || !pBar->IsWindowEnabled())
48
        {
49
          continue;
50
        }
51
52
        // get the old position, do the scrolling, and
53
        // then trigger the repaint
54
55
        int nOldPos = pBar->GetScrollPos();
56
57
        if (pView->DoMouseWheel(fFlags, zDelta, point))
58
          bRetVal = TRUE;
59
60
        if (bHasVert && col < m_nCols -1)
61
          pBar->SetScrollPos(nOldPos, FALSE);
62
        else if (!bHasVert && row < m_nRows -1)
63
          pBar->SetScrollPos(nOldPos, FALSE);
64
65
      }
66
    }
67
  }
68
69
  return TRUE;
70
}

Was, zum Teufel, geht das ein CSplitterWnd an, welchen View ich in 
welche Pane lege? Der soll einfach nur den Pane raussuchen, an den die 
Message zu senden ist und die Message weitergeben. Und ansonsten soll er 
sich da raushalten! Nicht alle Views benutzen das Mousewheel zum 
Scrollen. Manche, zb Grafikprogramme hängen an das Mouserad zb die 
Zoom-Steuerung - selbst dann wenn sie Scrollbars im View haben. Und das 
die Message überhaupt nicht weitergeroutet wird, wenn der View nicht von 
CScrollView abgeleitet ist, ist überhaupt nicht zu akzeptieren - was 
haben die Leute damals blos geraucht um auf so eine Schwachsinnsidee zu 
kommen?

Von solchen logischen Böcken gibt es in der MFC einige.


(Und nachdem ich das gesagt habe, out ich mich: Ich programmier immer 
noch gerne mit der MFC.)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.