Verwendung von HINSTANCE__...



  • groovemaster
    Nein, ich präsentiere das keinen Linuxprogrammierern sondern den Leutchen von der IHK, und ja: Ich musste das 1. mal begründen was das ist! Beim 2. mal hab ich Standardwerte genommen und Ruhe war.

    Und das mit "Ja, und dass uns der Himmel auf den Kopf fällt auch." empfinde ich als Wunschdenken. Dazu handelt es sich um eine Anfängerseite wo wie 1310-Logik es schon sagte, es ihn verwirrt das man UINT und co. benutzt.

    Also bitte, langsam wird es echt lächerlich mit dieser Diskusion. Das führt genau wieder zu so einer absurden Diskusion von wegen "size_t vs. unsigned long/int/short usw."



  • Aber ich mach es trotzdem so, wies in der MSDN steht.
    Weil sonst hab ich ein komplettes Durcheinander.
    Nur verstehn und einsehn, dass alles andere Namen bekommt, tu ich nicht.
    Ein Tisch ist ein Tisch und nicht ein MOEBEL_BRETTMITZWEIVIERODERSECHSBEINENAUFARBEITSHOEHEUNDMANCHMALAUCHHOEHERODERTIEFER



  • 1310-Logik schrieb:

    Ich finde gerade die Typedefs machen die WinAPI Codes so kryptisch und unleserlich, und bauen eine Hemmschwelle für jemand der grad erst C++ gelern hat.

    Auf den ersten Blick: Ja. Auf den zweiten Blick: Im Gegenteil.

    Du hälst Dich mit diesen ganzen typedefs portabel. Es ist Dir sogar beinahe egal, ob Du nun C oder C++ verwendest. Die älteren C Compiler kennen da z.B. kein bool, kein true und kein false. Verwendest Du durchgängig die typedefs, geht's überall, auch in Sprachen ohne C.

    Und wenn Du nun C verwendest, nicht C++, bleibt Dir ohne typedef sowieso nur Patricks Schreibweise. Aber an Übersicht gewinnst Du rein gar nichts. Wenn Du beispielsweise für eine Funktion eine Struktur des Typen RECT benötigst, schreibst Du

    // ohne typedef
    struct tagRECT rc;
    
    // oder eben mit
    RECT rc;
    

    Ich kann nicht sehen, wo mir das typedef Übersicht entzieht. Genauso ist das bei der HINSTANCE:

    struct HINSTANCE__* inst;
    

    Was bringt es mir bitteschön an Übersicht, wenn ich weiß, daß inst auf eine Struktur zeigt, die mit nur einem Member daherkommt, der sich treffenderweise unused nennt? Das bleibt genauso Opaque wie zuvor, schlauer bist Du nun auch nicht.

    Ungewohnt sind lediglich die vielen verschiedenen Typen. Da mußt Du aber durch. Aber Du hast ja die typedefs. Die helfen Dir dabei, die Übersicht zu wahren und schnell ins Thema zu finden.

    Ein typedef für VOID bringt Dir natürlich nichts ein. Es ist aber Konsequent. Ein fürchterliches Mischmasch wäre deutlich schlimmer gekommen. Das kannst Du schön bei Patrick sehen: Mal so, mal so, und am Ende weiß keiner mehr so genau, was eigentlich gemeint war. Und es macht doch auch nichts, Du hast doch auch so erkannt, daß VOID und void die selbe Wichse sind.



  • Das mit der Portabilität stimmt natürlich schon.
    Ja und bei HINSTANCE machts ja noch Sinn, auch HWND, die hat man im Standard ja sowieso nicht, aber bei den Standard Typen wie int und float ist es echt komisch, und schreckt am Anfang ab.
    In meinen eigenen Klassen verwend ich ja dann wieder die Standards, und somit wird das ganze echt inkonsistent. Ich hab da keine Lust, denn WINAPI Style komplett zu übernehmen.
    Oder macht ihr das so, dass ihr in eigenen Klassen FLOATs und DWORDs benutzt, wenn diese nichts Windowsspezifisches drin haben?



  • Kenner des Patrick schrieb:

    Patrick kann man eh nicht überzeugen. Die Diskussion mit ihm ist ziemlich sinnlos. 😃 👍

    Musste ich gerade auch feststellen.

    🙄



  • 1310-Logik schrieb:

    Wieso muss es ein UINT sein anstatt ein unsigned int ?

    Soll ja Leute geben, die lieber UINT schreiben. Einfach weil's kürzer und kompakter ist. Privat verwende ich auch eigene typedefs und schreibe halt lieber uint. Wirklich missverstehen kann man das eigentlich nicht.

    1310-Logik schrieb:

    oder noch übler ein VOID statt void

    Tja, ist mir ehrlich gesagt auch ein Rätsel. Vermutlich wollte Microsoft die eigene Typisierung komplett durchziehen. Man muss sich halt immer klarmachen, dass C/C++ case-sensitive arbeitet und die WinAPI Typen nicht zum Standard gehören.

    1310-Logik schrieb:

    und ein FALSE statt false?

    Dazu muss man ein bisschen in der Historie nachschauen. WinAPI ist eine C API, und zur damaligen Zeit hatte C noch kein bool. Dashalb wurde ein eigener Typ BOOL geschaffen, für welchen man logischerweise auch FALSE und TRUE brauchte. Und false bzw. true ist einfach nicht garantiert kompatibel zu BOOL. Warum eine Umwandlung trotzdem funktioniert, liegt an der impliziten Umwandlung, die C bzw. C++ definiert (da BOOL gleich int). Das ist aber ein anderes Thema. Grundsätzlich sollte man das jedenfalls nicht mischen. false und true gehören zu bool, FALSE und TRUE zu BOOL. Man kann ja trotzdem das eine dem anderen zuweisen, ohne auf die implizite Umwandlung angewiesen zu sein, zB

    BOOL a = /*...*/;
    bool b = a != FALSE;
    BOOL c = b ? TRUE : FALSE;
    

    Viele werden trotzdem den impliziten Weg bevorzugen, nur muss man dann mit Warnungen seitens des Compilers rechnen. Ich habe mir deshalb angewöhnt, zumindest bei BOOL nach bool immer das

    != FALSE
    

    zu schreiben.

    1310-Logik schrieb:

    Nur verstehn und einsehn, dass alles andere Namen bekommt, tu ich nicht.

    Dass die WinAPI oftmals seltsame Bezeichner hat, ist ja bekannt ➡ Thema UN. Das ist aber auch nicht das Problem.

    1310-Logik schrieb:

    Aber ich mach es trotzdem so, wies in der MSDN steht.
    Weil sonst hab ich ein komplettes Durcheinander.

    Genau das ist der springende Punkt, den Patrick halt nicht versteht.

    Patrick schrieb:

    Nein, ich präsentiere das keinen Linuxprogrammierern sondern den Leutchen von der IHK

    ROFL, naja dazu sag ich mal nichts. Ich hoffe nur, dass du deren Verhalten nicht als Standard interpretierst. Ein WinAPI Programmierer weiss jedenfalls, was LPARAM etc. bedeutet und ist eher verwirrt, wenn du die aufgelösten Typen verwendest.

    Patrick schrieb:

    Also bitte, langsam wird es echt lächerlich mit dieser Diskusion. Das führt genau wieder zu so einer absurden Diskusion von wegen "size_t vs. unsigned long/int/short usw."

    Naja, ich will jetzt nicht diese Diskussion anheizen. Das ist ein anderes Thema. Nur gibt es halt immer wieder Leute, die sowas für sinnlos halten und stupide das benutzen, was sie auch vorher benutzt haben oder fälschlicherweise für richtig ansehen. Und wer nicht glaubt, dass size_t sinnvoll ist und weiter unsigned int oder gar nur int benutzt, wird spätestens bei der Umstellung auf 64 Bit Probleme bekommen. Und genau das könnte dir mit deinen aufgedröselten Typen auch passieren. Das heisst nicht, dass es definitiv passieren wird. Aber die Möglichkeit besteht. Warum sich also vollkommen unnötig das Leben schwer machen?

    btw:
    Ich poste niemals als Unreg. Solche Beiträge also nicht mir zuordnen.



  • 1310-Logik schrieb:

    In meinen eigenen Klassen verwend ich ja dann wieder die Standards, und somit wird das ganze echt inkonsistent. Ich hab da keine Lust, denn WINAPI Style komplett zu übernehmen.
    Oder macht ihr das so, dass ihr in eigenen Klassen FLOATs und DWORDs benutzt, wenn diese nichts Windowsspezifisches drin haben?

    Nein, natürlich nicht. Zumindest kann ich da für mich sprechen. Schon deshalb nicht, weil du dann ja immer auf <windows.h> angewiesen bist und Plattformunabhängigkeit zum Fremdwort wird. Das Zauberwort heisst Abstraktion. Wenn ich WinAPI Sachen verwende (zB Threads oder Performance Counter), dann werden diese Sachen gekapselt. Intern verwende ich die WinAPI Typen, nach aussen werden aber Standard Typen weitergegeben, zB

    float foo()
    {
        /*...*/
        return IrgendeineWinAPIFunktiondieFLOATzurueckgibt(/*...*/);
    }
    

    Und ich sehe auch kein Problem darin, wenn du die primitiven Typen plain kopierst, also FLOAT nach float oder LONG nach long oder UNIT nach unsigned int oder ...



  • Sry wenn ich da was ausgrabe, aber ich dachte das gehört ev. zum thema.
    folgende bezeichner versteh ich nicht:

    ::HWND__*               hwnd_;      // Fensterhandle
    
    ::IDirectDraw7*         directdraw7_;           // Hauptobjekt
    

    Wozu sind die :: vor den bezeichnern? ohne namespace davor kenn ich das nicht.

    oder hier auch bei den standard windows funktionen

    ::ShowWindow    (hwnd_, SW_SHOWNORMAL); 
    ::UpdateWindow  (hwnd_);
    

    ps: Hab das aus nem tut.



  • Wenn du den Scope Operator verwendest, ohne einen Bezeichner davorzuschreiben, dann wird der folgende Bezeichner im globalen Namensraum gesucht, anstatt im aktuellen oder explizit angegebenen Namensraum. IdR macht die Verwendung nur dann Sinn, wenn es gleiche Bezeichner gibt und man einen explizit ansprechen muss. Bei einer C API wie WinAPI macht das eigentlich keinen Sinn, da C keine Namensräume kennt. Und unter C++ sucht der Compiler die Namensräume nach oben hin sowieso ab und kommt irgendwann im globalen Namensraum an. Einige machen es trotzdem, wahrscheinlich einfach nur vorbeugend. Vielleicht gibt es ja im gleichen oder einem darüberliegenden Namensraum den gleichen Bezeichner. Naja ... ich verwende die explizite globale Scope Schreibweise jedenfalls nur dann, wenn ich sie brauche. Könnte evtl. sein, dass diesem Thema bei MFC mehr Bedeutung zukommt. Da kenne ich mich allerdings nicht wirklich aus.



  • Einen wirklich Sinn, den wohl alle auch unterstützen könnten, konnte ich da auch noch nicht erkennen. Ich benutze es allerdings auch ganz gerne. 🙂

    Wenn ich '::' vor den Bezeichnern und Funktionen schreibe, dann weiß ich, dass ist nichts von mir. Ich erkenne daran sofort, dass es sich um eine 'Fremd-Funktion' handelt, da ich meine Funktionen (natürlich) in Namespaces packe. 😃

    Aber ich bin auch jmd. der bei Memberfunktionen bzw. eigenen Methodenaufrufen gerne ein 'this->' davorschreibt, weil ich so super sehen kann, dass es sich um einen Methodenaufruf und nicht etwa um den Aufruf einer globalen Funktion handelt.

    Manche mögen's, andere nicht, jedem das seine. 🙂



  • Eigentlich ging's ja um die verwendung von "ge-typedef'ten" API-Typen.

    Ich persönlich find es - vor allem in der Windows API - extrem hässlich

    UINT  x;
        UCHAR y;
    
        // oder
    
        SHORT z;
    

    zu schreiben. Bei einem

    HINSTANCE instance;
    

    halte ich es jedoch für groben Unfug, daraus

    HINSTANCE__ *instance;
    

    zu machen, da dadurch nicht mehr Klarheit herrscht als zuvor.

    Greetz, Swordfish


Anmelden zum Antworten