385 lines
14 KiB
C++
385 lines
14 KiB
C++
//-----------------------------------------------------------------------------
|
|
// File: UserDlg.cpp
|
|
//
|
|
// Desc: Support functions for the user select driver dialog.
|
|
|
|
// Note: Since this code is destined for a static link library, the
|
|
// dialog dox is constructed manually. Otherwise, we would use a resource
|
|
// and save many lines of code. Manually constructing dialog boxes is not
|
|
// trivial and there are many issues (unicode, dword alignment, etc.)
|
|
// involved.
|
|
//
|
|
//
|
|
// Copyright (c) 1997-1998 Microsoft Corporation. All rights reserved.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define STRICT
|
|
#include <tchar.h>
|
|
#include "D3DEnum.h"
|
|
#include <stdio.h>
|
|
#include "d3dutil.h"
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Constants and function prototypes for the user select driver dialog
|
|
//-----------------------------------------------------------------------------
|
|
#define IDC_STATIC 0xffff
|
|
#define IDC_DRIVER_COMBO 1000
|
|
#define IDC_DEVICE_COMBO 1001
|
|
#define IDC_MODE_COMBO 1002
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// External variables (declared in the D3DEnum.cpp file)
|
|
//-----------------------------------------------------------------------------
|
|
extern D3DEnum_DriverInfo* g_pCurrentDriver; // The selected DD driver
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: CopyToWideChar
|
|
//-----------------------------------------------------------------------------
|
|
static VOID CopyToWideChar( WCHAR** pstrOut, LPTSTR strIn )
|
|
{
|
|
DWORD dwLen = lstrlen( strIn );
|
|
WCHAR* strOut = *pstrOut;
|
|
|
|
#ifdef UNICODE // Copy Unicode to Unicode
|
|
_wcsncpy( strOut, strIn, dwLen );
|
|
strOut[dwLen] = L'\0';
|
|
#else // Copy Ansi to Unicode
|
|
dwLen = MultiByteToWideChar( CP_ACP, 0, strIn, dwLen, strOut, dwLen );
|
|
strOut[dwLen++] = L'\0'; // Add the null terminator
|
|
#endif
|
|
*pstrOut += dwLen;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: AddDialogControl()
|
|
// Desc: Internal function to help build the user select dialog
|
|
//-----------------------------------------------------------------------------
|
|
static VOID AddDialogControl( WORD** pp, DWORD dwStyle, SHORT x, SHORT y,
|
|
SHORT cx, SHORT cy, WORD id,
|
|
LPTSTR strClassName, LPTSTR strTitle )
|
|
{
|
|
// DWORD align the current ptr
|
|
DLGITEMTEMPLATE* p = (DLGITEMTEMPLATE*)(((((ULONG)(*pp))+3)>>2)<<2);
|
|
|
|
p->style = dwStyle | WS_CHILD | WS_VISIBLE;
|
|
p->dwExtendedStyle = 0L;
|
|
p->x = x;
|
|
p->y = y;
|
|
p->cx = cx;
|
|
p->cy = cy;
|
|
p->id = id;
|
|
|
|
*pp = (WORD*)(++p); // Advance ptr
|
|
|
|
CopyToWideChar( (WCHAR**)pp, strClassName ); // Set Class name
|
|
CopyToWideChar( (WCHAR**)pp, strTitle ); // Set Title
|
|
|
|
(*pp)++; // Skip Extra Stuff
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: _BuildUserSelectDialog()
|
|
// Desc: Internal function to build the user select dialog
|
|
//-----------------------------------------------------------------------------
|
|
DLGTEMPLATE* _BuildDriverSelectTemplate()
|
|
{
|
|
// Allocate ample memory for building the template
|
|
DLGTEMPLATE* pDlgTemplate = new DLGTEMPLATE[50];
|
|
if( NULL == pDlgTemplate )
|
|
return NULL;
|
|
ZeroMemory( pDlgTemplate, 50*sizeof(DLGTEMPLATE) );
|
|
|
|
// Fill in the DLGTEMPLATE info
|
|
DLGTEMPLATE* pdt = pDlgTemplate;
|
|
pdt->style = DS_MODALFRAME | DS_NOIDLEMSG | DS_SETFOREGROUND |
|
|
DS_3DLOOK | DS_CENTER | WS_POPUP | WS_VISIBLE |
|
|
WS_CAPTION | WS_SYSMENU | DS_SETFONT;
|
|
pdt->dwExtendedStyle = 0L;
|
|
pdt->cdit = 8;
|
|
pdt->x = 0;
|
|
pdt->y = 0;
|
|
pdt->cx = 179;
|
|
pdt->cy = 84;
|
|
|
|
// Add menu array, class array, dlg title, font size and font name
|
|
WORD* pw = (WORD*)(++pdt);
|
|
*pw++ = L'\0'; // Set Menu array to nothing
|
|
*pw++ = L'\0'; // Set Class array to nothing
|
|
CopyToWideChar( (WCHAR**)&pw, TEXT( "Select New Direct3D Driver" ) ); // Dlg title
|
|
*pw++ = 8; // Font Size
|
|
CopyToWideChar( (WCHAR**)&pw, TEXT("Arial") ); // Font Name
|
|
|
|
// Add the okay button
|
|
AddDialogControl( &pw, BS_PUSHBUTTON | WS_TABSTOP, 65, 65, 51, 14,
|
|
IDOK, TEXT("BUTTON"), TEXT("OK") );
|
|
|
|
// Add the cancel button
|
|
AddDialogControl( &pw, BS_PUSHBUTTON | WS_TABSTOP, 123, 65, 51, 14,
|
|
IDCANCEL, TEXT("BUTTON"), TEXT("Cancel") );
|
|
|
|
// Add the driver select combobox
|
|
AddDialogControl( &pw, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP,
|
|
36, 5, 138, 45,
|
|
IDC_DRIVER_COMBO, TEXT("COMBOBOX"), TEXT("") );
|
|
|
|
// Add the device select combobox
|
|
AddDialogControl( &pw, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP,
|
|
36, 24, 138, 45,
|
|
IDC_DEVICE_COMBO, TEXT("COMBOBOX"), TEXT("") );
|
|
|
|
// Add the mode select combobox
|
|
AddDialogControl( &pw, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP,
|
|
36, 44, 138, 45,
|
|
IDC_MODE_COMBO, TEXT("COMBOBOX"), TEXT("") );
|
|
|
|
// Add the "Driver:" text
|
|
AddDialogControl( &pw, SS_LEFT, 5, 5, 22, 13,
|
|
IDC_STATIC, TEXT("STATIC"), TEXT("Driver:") );
|
|
|
|
// Add the "Device:" text
|
|
AddDialogControl( &pw, SS_LEFT, 5, 24, 25, 13,
|
|
IDC_STATIC, TEXT("STATIC"), TEXT("Device:") );
|
|
|
|
// Add the "Mode:" text
|
|
AddDialogControl( &pw, SS_LEFT, 5, 44, 22, 13,
|
|
IDC_STATIC, TEXT("STATIC"), TEXT("Mode:") );
|
|
|
|
return pDlgTemplate;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: UpdateComboBoxesContent()
|
|
// Desc: Builds the list of drivers, devices and modes for the combo boxes
|
|
// in the driver select dialog box.
|
|
//-----------------------------------------------------------------------------
|
|
static VOID UpdateComboBoxesContent( HWND hDlg,
|
|
D3DEnum_DriverInfo** ppCurrentDriver,
|
|
D3DEnum_DeviceInfo** ppCurrentDevice,
|
|
D3DEnum_ModeInfo** ppCurrentMode,
|
|
BOOL bWindowed )
|
|
{
|
|
// Check the parameters
|
|
if( (NULL==ppCurrentDriver) || (NULL==ppCurrentDevice) ||
|
|
(NULL==ppCurrentMode) )
|
|
return;
|
|
|
|
// If the specified driver is NULL, use the first one in the list
|
|
if( NULL == *ppCurrentDriver)
|
|
(*ppCurrentDriver) = D3DEnum_GetFirstDriver();
|
|
|
|
// If the specified device is NULL, use the first one in the list
|
|
if( NULL == *ppCurrentDevice)
|
|
(*ppCurrentDevice) = (*ppCurrentDriver)->pFirstDevice;
|
|
|
|
// Reset the content in each of the combo boxes
|
|
SendDlgItemMessage( hDlg, IDC_DRIVER_COMBO, CB_RESETCONTENT, 0, 0 );
|
|
SendDlgItemMessage( hDlg, IDC_DEVICE_COMBO, CB_RESETCONTENT, 0, 0 );
|
|
SendDlgItemMessage( hDlg, IDC_MODE_COMBO, CB_RESETCONTENT, 0, 0 );
|
|
|
|
// Build the list of drivers for the combo box
|
|
for( D3DEnum_DriverInfo* pDriver = D3DEnum_GetFirstDriver(); pDriver;
|
|
pDriver = pDriver->pNext )
|
|
{
|
|
// Add driver desc to the combo box
|
|
DWORD dwItem = SendDlgItemMessage( hDlg, IDC_DRIVER_COMBO,
|
|
CB_ADDSTRING, 0, (LPARAM)pDriver->strDesc );
|
|
|
|
// Associate DriverInfo ptr with the item in the combo box
|
|
SendDlgItemMessage( hDlg, IDC_DRIVER_COMBO, CB_SETITEMDATA,
|
|
(WPARAM)dwItem, (LPARAM)pDriver );
|
|
|
|
// If this is the current driver, set is as the current selection
|
|
if( pDriver == (*ppCurrentDriver) )
|
|
SendDlgItemMessage( hDlg, IDC_DRIVER_COMBO, CB_SETCURSEL,
|
|
(WPARAM)dwItem, 0L );
|
|
}
|
|
|
|
// Build the list of devices for the combo box
|
|
for( D3DEnum_DeviceInfo* pDevice = (*ppCurrentDriver)->pFirstDevice; pDevice;
|
|
pDevice = pDevice->pNext )
|
|
{
|
|
// Add device name to the combo box
|
|
DWORD dwItem = SendDlgItemMessage( hDlg, IDC_DEVICE_COMBO,
|
|
CB_ADDSTRING, 0, (LPARAM)pDevice->strName );
|
|
|
|
// Associate DeviceInfo ptr with the item in the combo box
|
|
SendDlgItemMessage( hDlg, IDC_DEVICE_COMBO, CB_SETITEMDATA,
|
|
(WPARAM)dwItem, (LPARAM)pDevice );
|
|
|
|
// If this is the current device, set this as the current selection
|
|
if( pDevice == (*ppCurrentDevice) )
|
|
SendDlgItemMessage( hDlg, IDC_DEVICE_COMBO, CB_SETCURSEL,
|
|
(WPARAM)dwItem, 0L );
|
|
}
|
|
|
|
if( (*ppCurrentDriver)->ddDriverCaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED
|
|
&& ( NULL == (*ppCurrentDriver)->pGUID )
|
|
&& (*ppCurrentDevice)->bCompatbileWithDesktop )
|
|
{
|
|
// Add windowed mode to the combo box of available modes
|
|
DWORD dwItem = SendDlgItemMessage( hDlg, IDC_MODE_COMBO,
|
|
CB_ADDSTRING, 0, (LPARAM)TEXT("Windowed mode") );
|
|
|
|
// Associate ModeInfo ptr with the item in the combo box
|
|
SendDlgItemMessage( hDlg, IDC_MODE_COMBO, CB_SETITEMDATA,
|
|
(WPARAM)dwItem, (LPARAM)NULL );
|
|
|
|
// If the current device is windowed, set this as current
|
|
if( bWindowed )
|
|
SendDlgItemMessage( hDlg, IDC_MODE_COMBO, CB_SETCURSEL,
|
|
(WPARAM)dwItem, 0L );
|
|
}
|
|
|
|
// Build the list of modes for the combo box
|
|
for( D3DEnum_ModeInfo* pMode = (*ppCurrentDevice)->pFirstMode; pMode;
|
|
pMode = pMode->pNext )
|
|
{
|
|
// Add mode desc to the combo box
|
|
DWORD dwItem = SendDlgItemMessage( hDlg, IDC_MODE_COMBO,
|
|
CB_ADDSTRING, 0,
|
|
(LPARAM)pMode->strDesc );
|
|
|
|
// Associate ModeInfo ptr with the item in the combo box
|
|
SendDlgItemMessage( hDlg, IDC_MODE_COMBO, CB_SETITEMDATA,
|
|
(WPARAM)dwItem, (LPARAM)pMode );
|
|
|
|
// If this is the current mode, set is as the current selection
|
|
if( !bWindowed && ( pMode == (*ppCurrentMode) ) )
|
|
SendDlgItemMessage( hDlg, IDC_MODE_COMBO, CB_SETCURSEL,
|
|
(WPARAM)dwItem, 0L );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: _DriverSelectProc()
|
|
// Desc: Windows message handling function for the driver select dialog
|
|
//-----------------------------------------------------------------------------
|
|
BOOL CALLBACK _DriverSelectProc( HWND hDlg, UINT uiMsg, WPARAM wParam,
|
|
LPARAM lParam )
|
|
{
|
|
static D3DEnum_DriverInfo *pOldDriver, *pNewDriver;
|
|
static D3DEnum_DeviceInfo *pOldDevice, *pNewDevice;
|
|
static D3DEnum_ModeInfo *pOldMode, *pNewMode;
|
|
static BOOL bOldWindowed, bNewWindowed;
|
|
|
|
// Handle the initialization message
|
|
if( WM_INITDIALOG == uiMsg )
|
|
{
|
|
// Setup temp storage pointers for dialog
|
|
pNewDriver = pOldDriver = g_pCurrentDriver;
|
|
pNewDevice = pOldDevice = pOldDriver->pCurrentDevice;
|
|
pNewMode = pOldMode = pOldDevice->pCurrentMode;
|
|
bNewWindowed = bOldWindowed = pOldDevice->bWindowed;
|
|
|
|
UpdateComboBoxesContent( hDlg, &pOldDriver, &pOldDevice,
|
|
&pOldMode, bOldWindowed );
|
|
return TRUE;
|
|
}
|
|
|
|
if( WM_COMMAND == uiMsg )
|
|
{
|
|
// Handle the case when the user hits the OK button
|
|
if( IDOK == LOWORD(wParam) )
|
|
{
|
|
// Check if any of the options were changed
|
|
if( ( pOldDriver != pNewDriver ) || ( pOldDevice != pNewDevice ) ||
|
|
( pOldMode != pNewMode ) || ( bOldWindowed != bNewWindowed ) )
|
|
{
|
|
// Set actual ptrs from the temp ptrs used for the dialog
|
|
g_pCurrentDriver = pNewDriver;
|
|
g_pCurrentDriver->pCurrentDevice = pNewDevice;
|
|
g_pCurrentDriver->pCurrentDevice->pCurrentMode = pNewMode;
|
|
g_pCurrentDriver->pCurrentDevice->bWindowed = bNewWindowed;
|
|
|
|
EndDialog( hDlg, IDOK );
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
EndDialog( hDlg, IDCANCEL );
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
// Handle the case when the user hits the Cancel button
|
|
else if( IDCANCEL == LOWORD(wParam) )
|
|
{
|
|
EndDialog( hDlg, IDCANCEL );
|
|
return TRUE;
|
|
}
|
|
|
|
// Handle the case when the user chooses an item in the combo boxes.
|
|
else if( CBN_SELENDOK == HIWORD(wParam) )
|
|
{
|
|
DWORD dwIndex = SendMessage( (HWND)lParam, CB_GETCURSEL,
|
|
0, 0 );
|
|
LONG pNewObject = SendMessage( (HWND)lParam, CB_GETITEMDATA,
|
|
dwIndex, 0 );
|
|
|
|
if( (CB_ERR==dwIndex) )
|
|
return TRUE;
|
|
|
|
// Handle the case where one of these may have changed. The
|
|
// combo boxes will need to be updated to reflect the changes.
|
|
switch( LOWORD( wParam ) )
|
|
{
|
|
case IDC_DRIVER_COMBO:
|
|
if( pNewObject && pNewObject != (LONG)pNewDriver )
|
|
{
|
|
pNewDriver = (D3DEnum_DriverInfo*)pNewObject;
|
|
pNewDevice = pNewDriver->pCurrentDevice;;
|
|
pNewMode = pNewDevice->pCurrentMode;
|
|
bNewWindowed = pNewDevice->bWindowed;
|
|
}
|
|
break;
|
|
case IDC_DEVICE_COMBO:
|
|
if( pNewObject && pNewObject != (LONG)pNewDevice )
|
|
{
|
|
pNewDevice = (D3DEnum_DeviceInfo*)pNewObject;
|
|
pNewMode = pNewDevice->pCurrentMode;
|
|
bNewWindowed = pNewDevice->bWindowed;
|
|
}
|
|
break;
|
|
case IDC_MODE_COMBO:
|
|
if( pNewObject )
|
|
{
|
|
pNewMode = (D3DEnum_ModeInfo*)pNewObject;
|
|
bNewWindowed = FALSE;
|
|
}
|
|
else
|
|
bNewWindowed = TRUE;
|
|
break;
|
|
}
|
|
|
|
UpdateComboBoxesContent( hDlg, &pNewDriver, &pNewDevice,
|
|
&pNewMode, bNewWindowed );
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|