Buchempfehlung
Windows System Programming
Windows System Programming
Das Kompendium liefert viele interessante Informationen zur Windows-Programmierung auf Englisch. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Tutorial

Erste Schritte in der WinAPI mit Freebasic und FBEdit

von MitgliedstephanbrunkerSeite 2 von 13

Aufbau eines WinGUI - Programms in Freebasic

Das Projekt besteht wie jedes WInGUI-Programm aus (mindestens) drei Dateien:

(Den Quellcode für die Rescource-Datei erhält man, indem man die rc-Datei zuerst mit F4 schließt und dann mit gedrückter STRG-Taste erneut öffnet (im Projekt-Fenster). Das ist aber nur von Belang, wenn man nicht mit FBEDit arbeitet)

Der Recourceditor ist etwas anders als die Codeeditoren für die *.bi und *.bas: Er hat eine Palette für die verfügbaren Elemente, mit denen man sich sein Fenster zusammenbauen kann. Von alleine passiert mit diesen Elementen aber nichts, wenn man den Code dann ausführt. Der Rescourcen-Editor erstellt nämlich nur die rc-Datei, Funktionen sind diesem Elementen erstmal nicht zugewiesen. In einem zweiten Schritt müssen die ID's der Elemente nämlich in die Dialog.bi übertragen werden:

Dialog.bi

'Define the Identifiers for the Window Elements
#Define IDD_DLG1 1000
#Define IDC_BTN1 1001
#Define IDC_EDT1 1002

'Storage for the important handles
Dim Shared As HWND hMain
Dim Shared As HINSTANCE hInstance

Dann kommen wir zum eigentlichen Programm, der
Dialog.bas, die in der Minimalversion so aussieht:

'Includes
#Include "windows.bi"
#Include "win\commctrl.bi"
#Include "win\shellapi.bi"

'Include our own *.bi
#Include "Dialog.bi"

Declare Function DlgProc(hWin As HWND, uMsg As UINT, wParam As WPARAM, lParam As LPARAM) As Integer

'================================================
'                   FUNCTIONS
'================================================

'GUI application entry point
Function wWinMain(hInst As HINSTANCE, lpCmdLine As LPTSTR, nCmdShow As Integer ) As Integer
    InitCommonControls
    Dim msg As MSG

    'copy Instance to global
    hInstance = hInst

    'create and show the Dialog
    hMain = CreateDialogParam(hInstance, MAKEINTRESCOURCE(IDD_DLG1), NULL, @DlgProc, NULL)

    'Message Loop
    Do While GetMessage(@msg, NULL, 0, 0)
        If IsDialogMessage(hMain, @msg) = 0 Then
            TranslateMessage(@msg)
            DispatchMessage(@msg)
        End If
    Loop

    Return TRUE

End Function

'The Window Callback function
Function DlgProc(hWin As HWND, uMsg As UINT, wParam As WPARAM, lParam As LPARAM) As Integer

    Select Case uMsg

        Case WM_COMMAND 'Message sent by Usercommand
            Select Case HiWord(wParam)

                Case BN_CLICKED     'Left Mousebutton
                    Select Case LoWord(wParam)

                        Case IDC_BTN1       'Click on BTN1
                            SetDlgItemText(hWin, IDC_EDT1, @"Hello World!") 'Set Text in Editwindow

                        Case Else
                            Return FALSE
                    End Select

                Case Else
                    Return FALSE
            End Select


        Case WM_CLOSE       'Window Close Button
            DestroyWindow(hWin)

        Case WM_DESTROY 'Window Destroy
            PostQuitMessage(NULL)

        Case Else
            Return FALSE
    End Select

    Return TRUE

End Function

'================================================
'       PROGRAM START
'================================================

'Start Program
wWinMain(GetModuleHandle(NULL), GetCommandLine(), SW_SHOW)

'End Program
ExitProcess(0)

End

Das Programm beginnt mit den Includes, also die "Windows.bi" und andere, dann unsere eigene "Dialog.bi". Dann folgen die Funktionen. Die erste ist das Main-Programm, es initialisiert die Programminstanz, erzeugt das Fenster aus der rc-Datei mit CreateDialogParam und beginnt dann mit der Message-Loop. Die vom Fenster oder User erzeugten Messages, also Button gedrückt oder Text in Feld anzeigen werden von dieser Schleife ohne unser zutun sortiert und verschickt und kommen früher oder später in der Funktion an, die wir bei der Fenstererzeugung angegeben haben, der Callbackfunktion -hier also die DlgProc. Wenn das Fenster geschlossen wird, verlässt das Programm die Schleife und beendet sich. FreeBasic benötigt diese wWinMain-Funktion nicht unbedingt (man könnte den Code auch ganz unten in die Datei schreiben anstelle des Funktionsaufrufs), es ist aber die "saubere" Methode gleichlautend zu den Beispielen in der MSDN. Ich habe das selbst auch nicht konsequent gemacht und muss die anderen Beispiele noch umstellen.

Hinter der Main-Funktion folgen die anderen Funktionen, im Moment ist das nur die DlgProc. Zusätzliche Funktionen schreibt man entweder vor die DlgProc, damit man sie nicht deklarieren muss, oder gleich in separate Code-Dateien, die wir mit #Include einbinden.

Die Windows-Messages haben einen Code, z.B. WM_COMMAND, und übergeben die Parameter WPARAM und LPARAM. Der erste Parameter in der Function ist der Handle (Pointer - genauer HWND für HandleWindow) zum Fenster, von dem die Message stammt. Da jedes Element über seinen Handle identifiziert wird, empfiehlt es sich, wichtige Handles als shared-Variable zu speichern. Man kann die zwar auch jedesmal über GetDlgItem oder GetModuleHandle erfragen, aber das kann man sich dann sparen. Den Handle des Fensters braucht man mindestens so oft, aber der wird der Function als erster Parameter hWin übergeben

Unser Programm macht nun jetzt nicht viel: Wenn der User mit einem Klick auf den Button eine WM_COMMAND - message erzeugt, enthält diese Message im WPARAM (geteilt in HIWORD und LOWORD) die Informationen, mit welcher Maustaste geklickt wurde und auf welches Element - dessen Namen wir in der "Dialog.bi" hinterlegt haben. Das wird zweckmäßigerweise mit Select Case ausgelesen und dann kann man die gewünschte Aktion erzeugen, hier dann ein SetDlgItemText. Leider führt kein Weg daran vorbei, die Messages und Functions früher oder später in der MSDN nachzuschlagen, es gibt gefühlt unendlich viele davon. Auch hier ist die saubere Methode bei der Behandlung der Messages auf die behandelten mit Return TRUE zu antworten und auf die nicht behandelten mit FALSE (muss auch noch in den anderen Beispielen bereinigt werden).

Was man mit den Elementen anstellen kann, steht auf der nächsten Seite ...

 

Gehe zu Seite Gehe zu Seite  1  2  3  4  5  6  7  8  9  10  11  12  13  
Zusätzliche Informationen und Funktionen
  Bearbeiten Bearbeiten  

  Versionen Versionen