nderungen in GENERIC.H

#define IDM_ABOUT       100
#define IDM_HORZLIST    200
#define ID_LIST         300
#define ID_TEXT         400

int      PASCAL WinMain( HANDLE, HANDLE, LPSTR, int );
BOOL            InitApplication( HANDLE );
BOOL            InitInstance( HANDLE, int );
long FAR PASCAL MainWndProc( HWND, unsigned, WORD, LONG );
BOOL FAR PASCAL About( HWND, unsigned, WORD, LONG );
BOOL FAR PASCAL HorzListProc( HWND, unsigned, WORD, LONG );
long FAR PASCAL WndListBoxProc( HWND hWnd, unsigned message,
                                WORD wParam, LONG lParam );

nderungen in GENERIC.DEF

; Moduldefinitionsdatei fr den Linker, Programm GENERIC

NAME         Generic       ; Modulname

DESCRIPTION  'Sample Microsoft Windows Application'

EXETYPE      WINDOWS       ; eine Windows-Anwendung

STUB        'WINSTUB.EXE'  ; Fehlermeldung fr Start unter DOS

; Code ist verschiebbar und verwerfbar.
CODE  PRELOAD MOVEABLE DISCARDABLE

; Daten sind MULTIPLE, Programm kann mehrfach aufgerufen werden.
DATA  PRELOAD MOVEABLE MULTIPLE

HEAPSIZE     1024
STACKSIZE    5120   ; Empfohlenes Minimum

; Hier folgen die exportierten Funktionen

EXPORTS
    MainWndProc      @1    ; Haupt-Fensterfunktion
    About            @2    ; ber-Dialog
    HorzListProc     @3    ; HorzList-Dialogfunktion
    WndListBoxProc   @4    ; Abgeleitete Listenfunktion

nderungen in GENERIC.RC

#include "windows.h"
#include "generic.h"

GENERICMENU MENU DISCARDABLE
BEGIN
    POPUP    "&Test"
    BEGIN
        MENUITEM "&Horizontal-Scrolling List Box...", IDM_HORZLIST
    END

    POPUP    "&Help"
    BEGIN
        MENUITEM "&About Generic...", IDM_ABOUT
    END
END

AboutBox DIALOG 22, 17, 144, 75
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "About Generic"
BEGIN
    CTEXT "Microsoft Windows"     -1,     0,  5, 144,  8
    CTEXT "Generic Application"   -1,     0, 14, 144,  8
    CTEXT "Version 3.0"           -1,     0, 34, 144,  8
    DEFPUSHBUTTON "OK"          IDOK,    53, 59,  32, 14, WS_GROUP
END

HORZLISTBOX DIALOG DISCARDABLE  22, 17, 258, 123
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "Horizontal-Scrolling List Box"
FONT 8, "System"
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,113,100,32,14,WS_GROUP
    LISTBOX         ID_LIST,55,35,150,55,LBS_SORT
                    | LBS_NOINTEGRALHEIGHT | LBS_USETABSTOPS
                    | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP
    LTEXT           "",ID_TEXT,55,20,150,14
END

nderungen in GENERIC.C

// Globale Variablen am Anfang von GENERIC.C

static  HINSTANCE hInst;            // aktuelle Instanz
static  FARPROC lpProcHorzList;     // Zeiger auf HorzList-Funktion
static  FARPROC lpProcAbout;        // Zeiger auf ber-Funktion
static  FARPROC lpProcOrgProc;      // Zeiger auf alte Listenfunktion
static  FARPROC lpProcSubClassProc; // Zeiger auf abgeleitete Listenf.

static  UINT    uScrollMessage;     // selbstgemachte Benachrichtigung

/////////////////////////////////////////////////////////////////
// Ergnzung zur Instanz-Initialisierung

uScrollMessage = RegisterWindowMessage( "MyScrollNotificationMsg" );

/////////////////////////////////////////////////////////////////
// Ersatz fr WM_COMMAND-Abschnitt

case WM_COMMAND:    // Befehl via Menauswahl
    {
    switch (wParam)
        {
        case IDM_HORZLIST:
            {
            lpProcHorzList = MakeProcInstance(
                    (FARPROC)HorzListProc, hInst );
            lpProcSubClassProc = MakeProcInstance(
                    (FARPROC)WndListBoxProc, hInst );

            DialogBox( hInst, "HorzListBox",
                    hWnd, lpProcHorzList );

            FreeProcInstance( lpProcSubClassProc );
            FreeProcInstance( lpProcHorzList );
            return 0;
            }

        case IDM_ABOUT:
            {
            lpProcAbout = MakeProcInstance( About, hInst );

            DialogBox( hInst, "AboutBox", hWnd, lpProcAbout );

            FreeProcInstance( lpProcAbout );
            return 0;
            }

        default:
            // Der Rest ist fr Windows
            return DefWindowProc( hWnd, message, wParam, lParam );
        } // Ende von switch (wParam)
    } // Ende des WM_COMMAND-Abschnitts

/////////////////////////////////////////////////////////////////
//  Listenfeldfunktion mit erweitertem horizontalen Rollen

extern  BOOL FAR PASCAL HorzListProc
(
        HWND            hDlg,
        unsigned        message,
        WORD            wParam,
        LONG            lParam
)
{
auto    HWND            hWndListBox;
auto    char            buf[256];

if (message == uScrollMessage)
    {
    int     iMinPos,
            iMaxPos,
            iCurPos;

    hWndListBox = GetDlgItem( hDlg, ID_LIST );
    GetScrollRange( hWndListBox, SB_HORZ, &iMinPos, &iMaxPos );
    iCurPos = GetScrollPos( hWndListBox, SB_HORZ );
    wsprintf( buf, "Min: %d, Cur: %d, Max: %d",
            iMinPos, iCurPos, iMaxPos );
    SetDlgItemText( hDlg, ID_TEXT, buf );
    return 0;
    }

switch (message)
    {
    case WM_INITDIALOG:
        {
        char    c;

        // Fensternummer des Listenfensters einholen.
        hWndListBox = GetDlgItem( hDlg, ID_LIST );

        // Alte Listenfunktion ermitteln.
        lpProcOrgProc = (FARPROC)GetWindowLong(
                hWndListBox, GWL_WNDPROC );

        // Neue Listenfunktion einsetzen.
        SetWindowLong( hWndListBox, GWL_WNDPROC,
                (LONG)lpProcSubClassProc );

        // Ein paar Spieldaten fr die Liste...
        for (c = 'A';  c <= 'Z';  c++)
            {
            // Formatieren
            wsprintf( buf, "%c\tDies ist ein recht langer "
                    "Text zum Test der horizontalen Rollerei.\t%c",
                    c, c );

            // Text in die Liste aufnehmen.
            SendMessage( hWndListBox, LB_ADDSTRING, 0,
                    (LPARAM)(LPSTR)buf );
            }

        // Horizontale Rolleiste aktivieren
        SendMessage( hWndListBox,
                LB_SETHORIZONTALEXTENT, 500, 0L );

        // Eckdaten fr die horizontale Rolleiste setzen.
        SetScrollRange( hWndListBox, SB_HORZ, 0, 100, FALSE );
        SetScrollPos( hWndListBox, SB_HORZ, 0, FALSE );

        // Bildschirm aktualisieren.
        PostMessage( hDlg, uScrollMessage, wParam, lParam );

        return TRUE;
        }

    case WM_COMMAND:
        if (wParam == IDOK
        ||  wParam == IDCANCEL)
            {
            // Fensternummer der Liste ermitteln.
            hWndListBox = GetDlgItem( hDlg, ID_LIST );

            // Alte Listenfunktion installieren.
            SetWindowLong( hWndListBox, GWL_WNDPROC,
                    (LONG)lpProcOrgProc );

            // ... und Dialogende.
            EndDialog( hDlg, TRUE );
            return TRUE;
            }
        break;
    }
return FALSE;
}


/////////////////////////////////////////////////////////////////
//  Abgeleitete Listenfunktion
//  Diese Funktion benachrichtigt das Elternfenster von den
//  horizontalen Rollereignissen.

extern  long FAR PASCAL WndListBoxProc
(
        HWND            hWnd,
        unsigned        wMsg,
        WORD            wParam,
        LONG            lParam
)
{
switch (wMsg)
    {
    // Wenn die Rolleiste ihr Elternfenster (in diesem Fall das
    // Listenfenster) ber ein horizontales Rollereignis infor-
    // miert, wird diese Nachricht auch an das Elternfenster
    // der Liste bermittelt.
    case WM_HSCROLL:
        {
        HWND hParentWnd;

        // Ermittel die Zugriffsnummer des Elternfensters der Liste.
        hParentWnd = GetWindowWord( hWnd, GWW_HWNDPARENT );

        // Hinterlege eine Benachrichtigung fr dieses Fenster.
        PostMessage( hParentWnd, uScrollMessage,
                wParam, lParam );
        }
    }

// Der Rest wird wie gewohnt bearbeitet.
return CallWindowProc( lpProcOrgProc, hWnd, wMsg, wParam, lParam );
}
