GUI-Entwicklung unter der WinAPI
-
Hallo,
und zwar wollte ich mal fragen, welche Nachteile ihr in der WinAPI speziell bei der GUI-Entwicklung seht. Gerad was Aufwand, optische Darstellungsmöglichkeiten, UserAbility, Abhängigkeiten angeht.
Danke
-
Nachteile gegenüber was oder wen?
-
Der Aufwand für ein GUI ist, wenn du es ausschließlich mit WinAPI machst, unverhältnismäßig groß. Du bist damit von Windows abhängig - was aber bei den gängigsten Frameworks wie MFC und VCL, WinForms etc. genauso der Fall ist. Dafür hast du die exakte Kontrolle über alles. Da sich Details aber auch in Frameworks i.d.R. problemlos durch direkten WinAPI-Einsatz regeln lassen, sollte das ebenfalls kein Grund sein, auf ein anständiges Framework zu verzichten.
-
ArgV04 schrieb:
Hallo,
und zwar wollte ich mal fragen, welche Nachteile ihr in der WinAPI speziell bei der GUI-Entwicklung seht. Gerad was Aufwand, optische Darstellungsmöglichkeiten, UserAbility, Abhängigkeiten angeht.
Danke
- schlechte Tool Unterstützung (z. B. Designer)
- wichtige Layouts fehlen (du musst erst mal Code schreiben der die Steuerelemente mit skaliert und positioniert)
- schlechte Unterstützung für C++ (du musst dir erst selber Wrapper klassen schreiben - der Code ist zwar schon Objektorientiert, aber es gibt keien Fertigen C++ Klassen)
-
Vertexwahn schrieb:
- schlechte Tool Unterstützung (z. B. Designer)
wer braucht sowas ?
Vertexwahn schrieb:
- wichtige Layouts fehlen (du musst erst mal Code schreiben der die Steuerelemente mit skaliert und positioniert)
das macht mana uch nur einmal, dann copy & paste wenn nicht sogar eine eigene lib
Vertexwahn schrieb:
- schlechte Unterstützung für C++ (du musst dir erst selber Wrapper klassen schreiben - der Code ist zwar schon Objektorientiert, aber es gibt keien Fertigen C++ Klassen)
wie ich vorher sagte, man schreibt nur einmal einen eigenen wrapper, danach ist alles kinderleicht, dann hat man den vorteil der winapi alles direkt unter kontrolle zu haben + den vorteil den man in den eigenen wrapper mit zusammenbastelt
ich selber bin von der MFC zur pure WinAPI gewechselt, und nachdem mein wrapper fuer alle windows gui elemente fertig ist - ist das zusammenbauen kinderleicht - und colle kontrolle
ich hab mich auch absichtlich gegen alle diversen lib's entschieden - mein wrapper {welcher komplett c++ orientiert ist} und mein liebes cpp - alles praechtig {=
-
audacia schrieb:
Der Aufwand für ein GUI ist, wenn du es ausschließlich mit WinAPI machst, unverhältnismäßig groß. Du bist damit von Windows abhängig - was aber bei den gängigsten Frameworks wie MFC und VCL, WinForms etc. genauso der Fall ist. Dafür hast du die exakte Kontrolle über alles. Da sich Details aber auch in Frameworks i.d.R. problemlos durch direkten WinAPI-Einsatz regeln lassen, sollte das ebenfalls kein Grund sein, auf ein anständiges Framework zu verzichten.
Wobei man sagen muss das es eine Menge plattformunabhängige GUI Libs für C++ mittelerweile gibt.
wxWidgets, GTKmm und QT sind nur 3 davon.
-
@Mr Evil
könnte ich deinen Wrapper mal sehen

-
wozu ?
im grunde besteht es daraus das man nur die klasse zb eine Buttonklasse subclasst {kann man auch erben} und dann die methoden benutzt
mal ein beispiel
ich habe
class CButtons{ private: HWND m_Handle; ELEMPOS m_Size; public: CButtons(void); void Create(const _tstring& strName, const ELEMPOS& pos, HWND hwndMain, const unsigned int& uiId); bool Destroy(); bool SetPos(const ELEMPOS& pos); bool SetText(const _tstring& strName); bool SetFont(const unsigned int& uiFont); bool SetFont(const HFONT& Font); bool Enable(); bool Disable(); bool Show(); bool Hide(); bool SetFocus(); _tstring Gettext() const; const HWND& GetHandle() const; unsigned int GetID() const; HFONT GetFont() const; const ELEMPOS& GetPos() const; unsigned int GetTextLen() const; };ELEMPOS ist dem RECT sehr aehnlich, nur das man links, oben, breite und hoehe angibt
und _tstring ist ein typedef von std::string btw str::wstringder einzigste aufruf ist dann in der main klasse
CButtons m_ButtonA;und dann in der OnCrate Prozedur
m_ButtonA.Create(_T("Main Button"), ELEMPOS(10, 10, 70, 20), m_hWnd, ID_BUTTON);
dann ist der button an der position mit angegebener breite, verschieben oder groesse veraendern mit SetPos, oder andere font zuweisen mit SetFont usw
standardmaessig wird der button immer mit der standard dialog font erstelltalle methoden returniern bool oder string usw - wenn man das handle braucht reicht das *.GetHandle() usw
hier als beispiel ist nur der button, ich hatte mich mal mit jemanden von hier ueber meinen wrapper unterhalten per mail, war recht interessant
alle anderen windows elemente sind auch so aehnlich gepackt, evtl ein bool mehr oder weniger bei create und noch diverse funktionen das ich spaeter beim entwickeln nur noch minimalstes winapi brauch {zb hab ich fuer checkboxen "OnClick()" methoden wo ich in der main klass nur diese einmal aufrufen lassen muss usw}
fuer meine main klasse hab ich meine schablone - copy&paste schon kann ich mich um die eigentlichen funktionen kuemmern
-
Hab mir auch mal ein GUI Framework gebastelt:
#include "VertexwahnLib.h" using namespace Vertexwahn::GUI; #define ORTHOGONAL_CAMERA_DISTANCE 900.0 #define ORTHOGONAL_CAMERA_NEAR_CLIP 300.0 #define ORTHOGONAL_CAMERA_FAR_CLIP 5000.0 class MyApplication : public Vertexwahn::Application::EventDriven { public: MyApplication() : MyWindow(L"World Editor"), m_Ogre3DWidget1(10,10,200,200), m_Ogre3DWidget2(340,10,200,200), m_Ogre3DWidget3(10,220,200,200), m_Ogre3DWidget4(340,220,200,200), tableLayout(0,0,400,400,2,2) { MyWindow.setDefaultCloseOperation(Vertexwahn::GUI::Window::EXIT_ON_CLOSE); tableLayout.add(&m_Ogre3DWidget1,0,0); tableLayout.add(&m_Ogre3DWidget2,0,1); tableLayout.add(&m_Ogre3DWidget3,1,0); tableLayout.add(&m_Ogre3DWidget4,1,1); tableLayout.m_ColumnWidthInPercentage.push_back(50); tableLayout.m_ColumnWidthInPercentage.push_back(50); tableLayout.m_RowHeightInPercentage.push_back(50); tableLayout.m_RowHeightInPercentage.push_back(50); tableLayout.setAnchor(RIGHT | LEFT | TOP |BOTTOM); MyWindow.setSize(600, 600); MyWindow.add(&tableLayout); // Position and orient the cameras m_Ogre3DWidget1.getCamera()->setProjectionType(Ogre::PT_ORTHOGRAPHIC); m_Ogre3DWidget1.getCamera()->setFixedYawAxis(false); m_Ogre3DWidget1.getCamera()->setPosition(ORTHOGONAL_CAMERA_DISTANCE * Ogre::Vector3::UNIT_Y); m_Ogre3DWidget1.getCamera()->setDirection(Ogre::Vector3::NEGATIVE_UNIT_Y); m_Ogre3DWidget1.getCamera()->setNearClipDistance(ORTHOGONAL_CAMERA_NEAR_CLIP); m_Ogre3DWidget1.getCamera()->setFarClipDistance(ORTHOGONAL_CAMERA_FAR_CLIP); m_Ogre3DWidget1.getCamera()->setPolygonMode(Ogre::PM_WIREFRAME); m_Ogre3DWidget1.getCamera()->setAutoAspectRatio(true); m_Ogre3DWidget2.getCamera()->setProjectionType(Ogre::PT_ORTHOGRAPHIC); m_Ogre3DWidget2.getCamera()->setFixedYawAxis(false); m_Ogre3DWidget2.getCamera()->setPosition(ORTHOGONAL_CAMERA_DISTANCE * Ogre::Vector3::NEGATIVE_UNIT_X); m_Ogre3DWidget2.getCamera()->setDirection(Ogre::Vector3::UNIT_X); m_Ogre3DWidget2.getCamera()->setNearClipDistance(ORTHOGONAL_CAMERA_NEAR_CLIP); m_Ogre3DWidget2.getCamera()->setFarClipDistance(ORTHOGONAL_CAMERA_FAR_CLIP); m_Ogre3DWidget2.getCamera()->setPolygonMode(Ogre::PM_WIREFRAME); m_Ogre3DWidget3.getCamera()->setProjectionType(Ogre::PT_ORTHOGRAPHIC); m_Ogre3DWidget3.getCamera()->setFixedYawAxis(false); m_Ogre3DWidget3.getCamera()->setPosition(ORTHOGONAL_CAMERA_DISTANCE * Ogre::Vector3::UNIT_Z); m_Ogre3DWidget3.getCamera()->setDirection(Ogre::Vector3::NEGATIVE_UNIT_Z); m_Ogre3DWidget3.getCamera()->setNearClipDistance(ORTHOGONAL_CAMERA_NEAR_CLIP); m_Ogre3DWidget3.getCamera()->setFarClipDistance(ORTHOGONAL_CAMERA_FAR_CLIP); m_Ogre3DWidget3.getCamera()->setPolygonMode(Ogre::PM_WIREFRAME); m_Ogre3DWidget4.getCamera()->setPosition(-55.0, 40.0, 140.0); m_Ogre3DWidget4.getCamera()->lookAt(-10.0, 20.0, 5.0); m_Ogre3DWidget4.getCamera()->setNearClipDistance(5.0); m_Ogre3DWidget4.getCamera()->setFarClipDistance(5000.0); m_Ogre3DWidget4.getCamera()->setAutoAspectRatio(true); MyWindow.show(); } private: Window MyWindow; Vertexwahn::GUI::TableLayout tableLayout; Ogre3DWidget m_Ogre3DWidget1; Ogre3DWidget m_Ogre3DWidget2; Ogre3DWidget m_Ogre3DWidget3; Ogre3DWidget m_Ogre3DWidget4; };Hier ein Screenshot
http://loop.servehttp.com/~vertexwahn/uploads/editor3.PNGProblem hierbei ist halt das ich ein eigenes Framework entwickelt habe, das nur ich kenne - hätte ich jetzt z. B. Qt verwendet oder GTK++ oder ein bekanntes anderes GUI Framework, dann hätten es andere Entwickler nicht so schwer sich in meinem Code zurecht zu finden. Außerdem stecken bestimmt noch einige Bugs im Framework, die Größtenteils nur durch mich gefixt werden können, da ich das Detailwissen habe - das lenkt mich von meinem eigentlichen Vorhaben noch weiter ab und es kostet mich Stunden ein Steuerelement wie eine TreeView Control zu integrieren. Naja - die WinAPI zu wrappern ist nicht immer die beste Lösung...