Einige Grundlegende Fragen zur Win32 API Programmierung



  • Hallo zusammen,
    ich arbeite gerade an einem kleinen Win32 API basiertem Projekt und hätte mal ein paar grundlegende Fragen bzgl. der Win32 API Programmierung:

    Controls zur Laufzeit erstellen - An welcher Stelle im Source?
    --------------------------------------------------------------
    Ich erstelle alle meine Menüs/Controls zur Laufzeit, also ohne Resourcen.

    Aktuell erstelle ich innerhalb von WinMain(), direkt nach dem das Fenster erstellt wurde, dort auch alle meine Controls und zeige dann erst das Fenster an.

    Im Netz habe ich jedoch verschiedene SourceCodes gesehen, wo die Erstellung der Controls zur Laufzeit an verschiedenen Stellen im Source gemacht werden:

    - Direkt innerhalb von Main(), nach der Erstellung des Fensters.
    - Erst im CALLBACK WinProc, und zwar bei WM_CREATE
    - Erst im CALLBACK WinProc, und zwar bei WM_INITDIALOG
    - Erst im CALLBACK WinProc, und zwar bei anderen WM_XXX - Stellen.

    Daher meine Frage, an welcher Stelle wäre es korrekt, die Controls zu erstellen; bzw. was wäre der saubere / bessere Weg etc?

    Resize von Controls - Welcher Befehl und wo im CALLBACK?
    --------------------------------------------------------
    Bisher benutze ich zum Resizen von Controls SetWindowPos(); jedoch habe ich im Netz gesehen, dass einige Leute das ganze anscheinend auch mit MoveWindow() machen. Auch hier würde ich gerne wissen, was richtig bzw sauberer / besser wäre und ob ich das besser bei WM_SIZE oder WM_SIZING machen soll... Oder evtl. in einer Procedure/Functions packen soll; und diese bei beiden Events aufrufen soll.

    Wo kann ich die MSDN Macros bzw deren SendMessage-Aufrufe einsehen?
    -------------------------------------------------------------------
    Mich würde interessieren, wo ich all diese MACROS wie z.B. ListView_SetItem() einsehen kann, bzw welcher SendMessage() Code sich hinter all den MACROS verbirgt. Für ListView_SetItem() ist mir klar, wass sich dahinter verbirgt.

    Ist bei Win32 API für 32/64 Bit Programme etwas zu beachten?
    ------------------------------------------------------------
    Gibt es hier etwas zu beachten, wenn man das Programm anstatt als 32 Bit Exe; auch als 64 Bit Exe Version erstellen will?

    Vielen Dank!



  • Ich behaupte mal: das hängt alles davon ab, was du machen möchtest und welchem Konzept deine Applikation/Bibliothek folgt. Die Schöpfer der API gingen davon aus, dass du in einem C-Programm eine WNDPROC pro Hauptfenster hast, und in WM_CREATE dann alle Unter-Controls per Control-ID erzeugt werden. WM_CREATE funktioniert bei allen Fenstern, also auch Containern in Fenster.

    WM_INITDIALOG gilt meines Wissens nur für Dialoge, weil Dialoge als Resourcen in die EXE eingebettet werden können. Controls werde aus der Resource kreiert und du kannst in WM_INITDIALOG dann Dinge nachbauen was eben noch fehlt. Ich habe damit aber noch nie gearbeitet und daher auch keine Erfahrung damit.

    Tja, und wenn ein Control erst erzeugt werden soll, wenn du auf einen Button klicks, dann ist die richtige Stelle in WM_COMMAND natürlich passend.

    Ich selbst benutze in C++ dafür Klassen und die erzeugen die Fenster und Controls auch immer hintereinander, damit die WinAPI keine meiner Pointer herumreichen muss.

    MoveWindow ist eher eine vereinfachte Form von SetWindowPos, denn dort kannst du per Flag festlegen, was genau geändert wird. Du erhälst demnach bestimmte Nachrichten wie WM_SIZE or WM_MOVE oder eben beides. Wenn du z.B. Designs oder automatische Verschiebung von vielen Fenstern benötigst (etwa als Reaktion von Fenstervergrößerungen), dann wäre DeferWindowPos() die richtige Funktion.
    In WM_SIZING oder WM_MOVING kannst du eine Aktion verweigern, bevor sie grafisch umgesetzt wird, also wenn der User etwas mit der Maus macht, was du nicht willst, wie z.B.: Größenbeschränkungen. WM_SIZE und WM_MOVE sind der korrektere Ort um Unter-Controls anzupassen. Den Code in Funktionen auszulagern erhöht die Übersicht, ist dem OS aber ziemlich egal 😉

    Das Kontext-Menü "Go to Definition" über dem Macro lässt dich in den Header springen wo es definitiert ist. Ich finde die zwar generell gut und übersichtlich, nutze aber öfter SendMessage direkt, weil manchmal nicht alle Features durch Macros abgebildet sind und so ist es einheitlicher immer Messages direkt zu senden. Ist aber Geschmackssache.

    Pointer-Längen sind natürlich zu beachtenm und dass oft statt LONG und DWORD dann LONG_PTR und DWORD_PTR benutzt werden müssen. Einige Funktionen haben Macros wie GetWindowLongPtr(), was dann nur auf GetWindowLong() zurückverweist. Alles was HANDLE, POINTER oder SIZE -artig ist sollte beachtet werden. Viele alte WPARAM- und LPARAM-Codes sind oft falsch, weil sie gegen DWORD/LONG gecastet werden und damit bits verlieren. Such mal 64 bit C++ auf der MSDN. Da gibt es Ratschläge für einige Szenarien.



  • Wenn es nicht unbedingt die schon etwas ältere WinApi sein muss, wäre ein Blick auf .NET / C# ratsam.
    Dort handhabt man solche Dinge sehr einfach und nach Belieben, auch während der Laufzeit. C-Kenntnisse reichen für den Einstieg.



  • Hi,

    WM_CREATE bzw. WM_INITDIALOG sind gute Gelegenheiten Childfenster zu erzeugen, weil das vor dem ersten Verschicken von WM_PAINT passiert. Dadurch vermeidest Du ein Flackern des Fensters.

    WM_SIZING ist für die Größe ungeschickt, da da dieses wohl nur verschickt wird, wenn der Benutzer eines der Sizer klickt. Nimm besser WM_SIZE, weil das reagiert auch auf die Maximize- und Minimize-Buttons.

    MoveWindow ist wahrscheinlich besser geeignet, weil das funktioniert für jedes Fenster gleich. SetWindowPos ist in erster Linie für Toplevel Fenster gemacht. Sollte aber eigentlich wurscht sein.

    Die MSDN Macros findest Du wohl in irgendeinem Headerfile. Wenn ich sowas brauche mache ist immer am Anfang einer Datei so ein Macro:

    #define Macro blöd
    

    Dann bekomme ich meistens vom Compiler eine Fehlermeldung an der gesuchten Stelle. 😃

    Ob es zwischen 64-Bit und 32 Bit große Unterschiede gibt in der API, kann ich nicht sagen, was ich so bisher mitbekommen habe, scheint es wohl so zu sein, daß Du nix großartiges beachten muß. wParam und lParam werden halt doppelt so breit sein. Das war beim Umstieg von 16 nach 32 bit nicht so. Schau aber am besten mal bei MSDN Vorbei, dort solltest Du die notwendige Info finden.

    mfg Martin


Log in to reply