865
09.04.2011, 11:54 Uhr
Matthias Hofmann
Administrator Bürstenkaiser
Themenstarter Beiträge: 4133 Dabei seit: 15.04.2003, 23:00 Uhr |
Gestern und heute habe ich wieder mal etwas Ordnung in den Quelltext von Klomanager II gebracht und ein Modul neu strukturiert, das die gewünschten Videoeinstellungen vom Benutzer erfragt. Den entsprechenden Dialog zu Beginn des Spiels kennt Ihr sicher bereits von Klomanager Deluxe und Kartoffelpüree. In Klomanager II sieht er im Moment so aus:
Was sich denn nun hinter den Kulissen geändert hat, möchte ich Euch am Beispiel der Funktion QueryProc() zeigen. Hier zunächst die alte Version, die zumindest auf den ersten Blick etwas unübersichtlich ist:
format_source('/*
* Description: Window procedure for the dialog box.
*
* Parameters: As usual for window procs.
*
* Return value: Depends on message processed.
*
*/
int CALLBACK QueryProc( HWND hWnd, UINT msg,
WPARAM wParam, LPARAM lParam )
{
static LPVIDEOSETTINGS lpvs;
HINSTANCE hInstance;
HMODULE hModule;
LPDIRECTDRAWENUMERATEEX EnumDevsEx;
int iIndex;
LPGUID lpGuid;
RECT rc;
switch ( msg )
{
case WM_INITDIALOG:
// Convert the passed parameter.
lpvs = ( LPVIDEOSETTINGS ) lParam;
// Retrieve a handle to the application instance.
hInstance = ( HINSTANCE ) GetWindowLong( hWnd, GWL_HINSTANCE );
// Set the icon to be displayed in the Alt+Tab dialog box.
SendMessage( hWnd, WM_SETICON, ICON_BIG, ( LPARAM ) LoadIcon(
hInstance, MAKEINTRESOURCE( IDI_MAIN ) ) );
// Load the DirectDraw library.
hModule = LoadLibrary( "ddraw.dll");
// Retrieve the address of the function that enumerates
// all display devices installed on the system.
EnumDevsEx = ( LPDIRECTDRAWENUMERATEEX ) GetProcAddress(
hModule, "DirectDrawEnumerateExA" );
if ( EnumDevsEx )
{
// Enumerate all display devices
// installed on the system.
EnumDevsEx( EnumDevsExCallback, hWnd,
DDENUM_ATTACHEDSECONDARYDEVICES );
}
else
{
// Enumerate only the primary display device.
DirectDrawEnumerate( EnumDevsCallback, hWnd );
}
// Select the first item in the list
// of available display devices.
SendDlgItemMessage( hWnd, IDC_DEVICE,
CB_SETCURSEL, 0, 0L );
// The DirectDraw library
// is not needed any more.
FreeLibrary( hModule );
// Set the position of the bitmap
// in dialog box units.
SetRect( &rc, 10, 10, 51, 48 );
// Map the rectangle to screen units.
MapDialogRect( hWnd, &rc );
// Adjust the position and size of the bitmap.
SetWindowPos( GetDlgItem( hWnd, IDC_MAIN ),
NULL, rc.left, rc.top, rc.right - rc.left,
rc.bottom - rc.top, SWP_NOZORDER );
// Set the default
// keyboard focus.
return true;
case WM_COMMAND:
switch ( LOWORD( wParam ) )
{
case IDC_START:
// Retrieve the index of the current
// selection in the list of available
// display devices.
iIndex = SendDlgItemMessage( hWnd,
IDC_DEVICE, CB_GETCURSEL, 0, 0L );
// Retrieve the GUID that identifies the
// currently selected display device.
lpGuid = ( LPGUID ) SendDlgItemMessage( hWnd,
IDC_DEVICE, CB_GETITEMDATA, iIndex, 0L );
// Retrieve the highest color depth supported
// by the display device.
lpvs->dwDepth = GetHighestColorDepth( lpGuid );
// Check whether the display device
// meets the system requirements.
if ( lpvs->dwDepth < MIN_DEPTH )
{
// Inform the user that the display device
// does not meet the system requirements.
MessageBox( hWnd, IDS_ERROR_VIDEOREQUIREMENTS,
IDS_ERROR_CAPTION, MB_OK | MB_ICONEXCLAMATION );
// Let the user choose another
// display device.
break;
}
if ( lpGuid )
{
// Copy the GUID and store
// its address.
lpvs->guid = *lpGuid;
lpvs->lpGuid = &lpvs->guid;
}
else
{
// A NULL pointer identifies
// the primary display device.
lpvs->lpGuid = NULL;
}
// Free the memory previously
// allocated for the GUIDs.
CleanUpComboBox( hWnd, IDC_DEVICE );
// Return that the
// user confirmed.
EndDialog( hWnd, 0 );
return true;
case IDC_STOP:
// Free the memory previously
// allocated for the GUIDs.
CleanUpComboBox( hWnd, IDC_DEVICE );
// Return that the
// user cancelled.
EndDialog( hWnd, 1 );
return true;
}
break;
}
return false;
}')Die neue Version ist dagegen viel überschaubarer. Das liegt daran, da� die Nachrichten "WM_INITDIALOG" und "WM_COMMAND" dort nicht mehr direkt behandelt werden. Statt dessen werden sie einfach an entsprechende Unterfunktionen weitergeleitet:
format_source('/*
* Description: The window procedure for the
* video settings dialog.
*
* Parameters: As usual for a dialog procedure.
*
* Return value: Depends on the message processed.
*
*/
int CALLBACK QueryProc( HWND hWnd, UINT msg,
WPARAM wParam, LPARAM lParam )
{
switch ( msg )
{
case WM_INITDIALOG:
// Process the message.
return OnInitDialog( hWnd, wParam, lParam );
case WM_COMMAND:
// Process the message.
return OnCommand( hWnd, wParam, lParam );
}
// Leave other messages
// to default processing.
return FALSE;
}')Der Anla� dieser Aufräumaktion war übrigens ein kleiner Fehler, dessen Korrektur vorher nicht so leicht möglich gewesen wäre. Die Details dazu möchte ich Euch allerdings ersparen, wer unbedingt mehr wissen will, der kann ja mal in der MSDN Library nach der Funktion SetWindowLong() suchen und sich die Erläuterungen zu DWL_MSGRESULT durchlesen. ----- Matthias Hofmann | Klomanager Deluxe jetzt bei Gamesload kaufen |