Initial commit: ROW Client source code

Game client codebase including:
- CharacterActionControl: Character and creature management
- GlobalScript: Network, items, skills, quests, utilities
- RYLClient: Main client application with GUI and event handlers
- Engine: 3D rendering engine (RYLGL)
- MemoryManager: Custom memory allocation
- Library: Third-party dependencies (DirectX, boost, etc.)
- Tools: Development utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-29 16:24:34 +09:00
commit e067522598
5135 changed files with 1745744 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define IDC_STATIC -1
#include <Windows.h>
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#define IDC_STATIC -1\r\n"
"#include <Windows.h>\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_MAIN_ICON ICON DISCARDABLE "DirectX.ico"
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_MAIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 251
TOPMARGIN, 7
BOTTOMMARGIN, 65
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MAIN DIALOG DISCARDABLE 0, 0, 258, 74
STYLE DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE |
WS_CAPTION | WS_SYSMENU
CAPTION "DirectInput ActionMapper Sample"
FONT 8, "MS Shell Dlg"
BEGIN
PUSHBUTTON "E&xit",IDCANCEL,187,51,64,14
PUSHBUTTON "Configure &Input",IDM_CONFIGINPUT,187,7,64,14
RTEXT "Left/Right Axis:",IDC_STATIC,7,37,59,8
RTEXT "World State:",IDC_STATIC,7,57,59,8
LTEXT "Use arrow keys or joystick to update input state",
IDC_STATIC,7,7,150,8
RTEXT "Up/Down Axis:",IDC_STATIC,7,27,59,8
LTEXT "Static",IDC_UD_AXIS_STATE,70,27,76,8
LTEXT "Static",IDC_LR_AXIS_STATE,70,37,76,8
LTEXT "Static",IDC_WORLD_STATE,70,57,76,8
RTEXT "Button State:",IDC_STATIC,7,47,59,8
LTEXT "Static",IDC_BUTTON_STATE,70,47,76,8
LTEXT "Click 'Configure Input' to view or change input settings",
IDC_STATIC,7,16,171,8
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,671 @@
//-----------------------------------------------------------------------------
// File: ActionMapper.cpp
//
// Desc: This is a simple sample to demonstrate how to code using the DInput
// action mapper feature.
//
//-----------------------------------------------------------------------------
#define STRICT
#include <windows.h>
#include <basetsd.h>
#include <math.h>
#include <stdio.h>
#include <DXErr8.h>
#include <tchar.h>
#include <dinput.h>
#include "DIUtil.h"
#include "DXUtil.h"
#include "resource.h"
//-----------------------------------------------------------------------------
// Defines, and constants
//-----------------------------------------------------------------------------
// This GUID must be unique for every game, and the same for
// every instance of this app. // {67131584-2938-4857-8A2E-D99DC2C82068}
// The GUID allows DirectInput to remember input settings
GUID g_guidApp = { 0x67131584, 0x2938, 0x4857, { 0x8a, 0x2e, 0xd9, 0x9d, 0xc2, 0xc8, 0x20, 0x68 } };
// DirectInput action mapper reports events only when buttons/axis change
// so we need to remember the present state of relevant axis/buttons for
// each DirectInput device. The CInputDeviceManager will store a
// pointer for each device that points to this struct
struct InputDeviceState
{
FLOAT fAxisMoveUD;
BOOL bButtonForwardThrust;
BOOL bButtonReverseThrust;
FLOAT fAxisRotateLR;
BOOL bButtonRotateLeft;
BOOL bButtonRotateRight;
BOOL bButtonFireWeapons;
BOOL bButtonEnableShield;
};
// Struct to store the current input state
struct UserInput
{
FLOAT fAxisMoveUD;
FLOAT fAxisRotateLR;
BOOL bButtonFireWeapons;
BOOL bButtonEnableShield;
BOOL bDoConfigureInput;
BOOL bDoQuitGame;
};
// Input semantics used by this app
enum INPUT_SEMANTICS
{
// Gameplay semantics
INPUT_ROTATE_AXIS_LR=1, INPUT_MOVE_AXIS_UD,
INPUT_FIREWEAPONS, INPUT_ENABLESHIELD,
INPUT_TURNLEFT, INPUT_TURNRIGHT,
INPUT_FORWARDTHRUST, INPUT_REVERSETHRUST,
INPUT_DISPLAYGAMEMENU, INPUT_QUITGAME,
};
// Actions used by this app
DIACTION g_rgGameAction[] =
{
// (C:\Program Files\DirectX\DirectInput\User Maps\*.ini)
// after changing this, otherwise settings won't reset and will be read
// from the out of date ini files
// Device input (joystick, etc.) that is pre-defined by DInput, according
// to genre type. The genre for this app is space simulators.
{ INPUT_ROTATE_AXIS_LR, DIAXIS_SPACESIM_LATERAL, 0, TEXT("Rotate left/right"), },
{ INPUT_MOVE_AXIS_UD, DIAXIS_SPACESIM_MOVE, 0, TEXT("Move"), },
{ INPUT_FIREWEAPONS, DIBUTTON_SPACESIM_FIRE, 0, TEXT("Fire weapons"), },
{ INPUT_ENABLESHIELD, DIBUTTON_SPACESIM_GEAR, 0, TEXT("Enable shield"), },
{ INPUT_DISPLAYGAMEMENU, DIBUTTON_SPACESIM_DISPLAY, 0, TEXT("Configure"), },
// Keyboard input mappings
{ INPUT_TURNLEFT, DIKEYBOARD_LEFT, 0, TEXT("Turn left"), },
{ INPUT_TURNRIGHT, DIKEYBOARD_RIGHT, 0, TEXT("Turn right"), },
{ INPUT_FORWARDTHRUST, DIKEYBOARD_UP, 0, TEXT("Forward thrust"), },
{ INPUT_REVERSETHRUST, DIKEYBOARD_DOWN, 0, TEXT("Reverse thrust"), },
{ INPUT_FIREWEAPONS, DIKEYBOARD_F, 0, TEXT("Fire weapons"), },
{ INPUT_ENABLESHIELD, DIKEYBOARD_S, 0, TEXT("Enable shield"), },
{ INPUT_DISPLAYGAMEMENU, DIKEYBOARD_D, DIA_APPFIXED, TEXT("Configure"), },
{ INPUT_QUITGAME, DIKEYBOARD_ESCAPE, DIA_APPFIXED, TEXT("Quit game"), },
};
#define NUMBER_OF_GAMEACTIONS (sizeof(g_rgGameAction)/sizeof(DIACTION))
//-----------------------------------------------------------------------------
// Function prototypes
//-----------------------------------------------------------------------------
INT_PTR CALLBACK StaticMsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
//-----------------------------------------------------------------------------
// Name: class CMyApplication
// Desc: Application class.
//-----------------------------------------------------------------------------
class CMyApplication
{
TCHAR* m_strWindowTitle; // Title for the app's window
HWND m_hWnd; // The main app window
FLOAT m_fTime; // Current time in seconds
FLOAT m_fElapsedTime; // Time elapsed since last frame
CInputDeviceManager* m_pInputDeviceManager; // DirectInput device manager
DIACTIONFORMAT m_diafGame; // Action format for game play
UserInput m_UserInput; // Struct for storing user input
FLOAT m_fWorldRotX; // World rotation state X-axis
FLOAT m_fWorldRotY; // World rotation state Y-axis
protected:
HRESULT OneTimeSceneInit();
HRESULT Render();
HRESULT FrameMove();
HRESULT FinalCleanup();
HRESULT InitInput( HWND hWnd );
void UpdateInput( UserInput* pUserInput );
void CleanupDirectInput();
public:
HRESULT Create( HINSTANCE hInstance );
INT Run();
INT_PTR MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
CMyApplication();
HRESULT InputAddDeviceCB( CInputDeviceManager::DeviceInfo* pDeviceInfo, const DIDEVICEINSTANCE* pdidi );
static HRESULT CALLBACK StaticInputAddDeviceCB( CInputDeviceManager::DeviceInfo* pDeviceInfo, const DIDEVICEINSTANCE* pdidi, LPVOID pParam );
};
//-----------------------------------------------------------------------------
// Global access to the app (needed for the global WndProc())
//-----------------------------------------------------------------------------
CMyApplication* g_pApp = NULL;
HINSTANCE g_hInst = NULL;
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Application entry point
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow )
{
CMyApplication app;
g_hInst = hInstance;
if( FAILED( app.Create( hInstance ) ) )
return 0;
return app.Run();
}
//-----------------------------------------------------------------------------
// Name: CMyApplication()
// Desc: Constructor
//-----------------------------------------------------------------------------
CMyApplication::CMyApplication()
{
g_pApp = this;
m_hWnd = NULL;
m_strWindowTitle = TEXT( "DirectInput ActionMapper Sample" );
m_pInputDeviceManager = NULL;
ZeroMemory( &m_UserInput, sizeof(m_UserInput) );
m_fWorldRotX = 0.0f;
m_fWorldRotY = 0.0f;
}
//-----------------------------------------------------------------------------
// Name: Create()
// Desc: Creates the window
//-----------------------------------------------------------------------------
HRESULT CMyApplication::Create( HINSTANCE hInstance )
{
// Display the main dialog box.
CreateDialog( hInstance, MAKEINTRESOURCE(IDD_MAIN),
NULL, StaticMsgProc );
if( NULL == m_hWnd )
return E_FAIL;
// Initialize the application timer
DXUtil_Timer( TIMER_START );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Run()
// Desc: Handles the message loop and calls FrameMove() and Render() when
// idle.
//-----------------------------------------------------------------------------
INT CMyApplication::Run()
{
MSG msg;
// Message loop to run the app
while( TRUE )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
// Skip WM_KEYDOWN so they aren't handled by the dialog
if( msg.message == WM_KEYDOWN )
continue;
if( !IsDialogMessage( m_hWnd, &msg ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
if( msg.message == WM_QUIT )
{
DestroyWindow( m_hWnd );
break;
}
}
else
{
// Update the time variables
m_fTime = DXUtil_Timer( TIMER_GETAPPTIME );
m_fElapsedTime = DXUtil_Timer( TIMER_GETELAPSEDTIME );
// This app uses idle time processing for the game loop
if( FAILED( FrameMove() ) )
SendMessage( m_hWnd, WM_DESTROY, 0, 0 );
if( FAILED( Render() ) )
SendMessage( m_hWnd, WM_DESTROY, 0, 0 );
Sleep( 20 );
}
}
FinalCleanup();
return (INT)msg.wParam;
}
//-----------------------------------------------------------------------------
// Name: OneTimeSceneInit()
// Desc: Called during initial app startup, this function performs all the
// permanent initialization.
//-----------------------------------------------------------------------------
HRESULT CMyApplication::OneTimeSceneInit()
{
// Initialize DirectInput
InitInput( m_hWnd );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: StaticInputAddDeviceCB()
// Desc: Static callback helper to call into CMyApplication class
//-----------------------------------------------------------------------------
HRESULT CALLBACK CMyApplication::StaticInputAddDeviceCB(
CInputDeviceManager::DeviceInfo* pDeviceInfo,
const DIDEVICEINSTANCE* pdidi,
LPVOID pParam )
{
CMyApplication* pApp = (CMyApplication*) pParam;
return pApp->InputAddDeviceCB( pDeviceInfo, pdidi );
}
//-----------------------------------------------------------------------------
// Name: InputAddDeviceCB()
// Desc: Called from CInputDeviceManager whenever a device is added.
// Set the dead zone, and creates a new InputDeviceState for each device
//-----------------------------------------------------------------------------
HRESULT CMyApplication::InputAddDeviceCB( CInputDeviceManager::DeviceInfo* pDeviceInfo,
const DIDEVICEINSTANCE* pdidi )
{
// Setup the deadzone
DIPROPDWORD dipdw;
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = 500;
pDeviceInfo->pdidDevice->SetProperty( DIPROP_DEADZONE, &dipdw.diph );
// Create a new InputDeviceState for each device so the
// app can record its state
InputDeviceState* pNewInputDeviceState = new InputDeviceState;
if (!pNewInputDeviceState)
return E_FAIL;
ZeroMemory( pNewInputDeviceState, sizeof(InputDeviceState) );
pDeviceInfo->pParam = (LPVOID) pNewInputDeviceState;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InitInput()
// Desc: Initialize DirectInput objects
//-----------------------------------------------------------------------------
HRESULT CMyApplication::InitInput( HWND hWnd )
{
HRESULT hr;
// Setup action format for the actual gameplay
ZeroMemory( &m_diafGame, sizeof(DIACTIONFORMAT) );
m_diafGame.dwSize = sizeof(DIACTIONFORMAT);
m_diafGame.dwActionSize = sizeof(DIACTION);
m_diafGame.dwDataSize = NUMBER_OF_GAMEACTIONS * sizeof(DWORD);
m_diafGame.guidActionMap = g_guidApp;
m_diafGame.dwGenre = DIVIRTUAL_SPACESIM;
m_diafGame.dwNumActions = NUMBER_OF_GAMEACTIONS;
m_diafGame.rgoAction = g_rgGameAction;
m_diafGame.lAxisMin = -100;
m_diafGame.lAxisMax = 100;
m_diafGame.dwBufferSize = 16;
_tcscpy( m_diafGame.tszActionMap, _T("ActionMapper Sample") );
// Create a new input device manager
m_pInputDeviceManager = new CInputDeviceManager();
if( FAILED( hr = m_pInputDeviceManager->Create( hWnd, NULL, m_diafGame,
StaticInputAddDeviceCB, this ) ) )
return DXTRACE_ERR_NOMSGBOX( TEXT("m_pInputDeviceManager->Create"), hr );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
// the scene.
//-----------------------------------------------------------------------------
HRESULT CMyApplication::FrameMove()
{
// Update user input state
UpdateInput( &m_UserInput );
// Respond to input
if( m_UserInput.bDoConfigureInput )
{
// One-shot per keypress
m_UserInput.bDoConfigureInput = FALSE;
// Get access to the list of semantically-mapped input devices
// to delete all InputDeviceState structs before calling ConfigureDevices()
CInputDeviceManager::DeviceInfo* pDeviceInfos;
DWORD dwNumDevices;
m_pInputDeviceManager->GetDevices( &pDeviceInfos, &dwNumDevices );
for( DWORD i=0; i<dwNumDevices; i++ )
{
InputDeviceState* pInputDeviceState = (InputDeviceState*) pDeviceInfos[i].pParam;
SAFE_DELETE( pInputDeviceState );
pDeviceInfos[i].pParam = NULL;
}
// Configure the devices (with edit capability)
m_pInputDeviceManager->ConfigureDevices( m_hWnd, NULL, NULL, DICD_EDIT, NULL );
}
// Update the world state according to user input
if( m_UserInput.fAxisRotateLR )
m_fWorldRotY += m_fElapsedTime * m_UserInput.fAxisRotateLR;
if( m_UserInput.fAxisMoveUD )
m_fWorldRotX += m_fElapsedTime * m_UserInput.fAxisMoveUD;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: UpdateInput()
// Desc: Update the user input. Called once per frame
//-----------------------------------------------------------------------------
void CMyApplication::UpdateInput( UserInput* pUserInput )
{
if( NULL == m_pInputDeviceManager )
return;
// Get access to the list of semantically-mapped input devices
CInputDeviceManager::DeviceInfo* pDeviceInfos;
DWORD dwNumDevices;
m_pInputDeviceManager->GetDevices( &pDeviceInfos, &dwNumDevices );
// Loop through all devices and check game input
for( DWORD i=0; i<dwNumDevices; i++ )
{
DIDEVICEOBJECTDATA rgdod[10];
DWORD dwItems = 10;
HRESULT hr;
LPDIRECTINPUTDEVICE8 pdidDevice = pDeviceInfos[i].pdidDevice;
InputDeviceState* pInputDeviceState = (InputDeviceState*) pDeviceInfos[i].pParam;
hr = pdidDevice->Acquire();
hr = pdidDevice->Poll();
hr = pdidDevice->GetDeviceData( sizeof(DIDEVICEOBJECTDATA),
rgdod, &dwItems, 0 );
if( FAILED(hr) )
continue;
// Get the sematics codes for the game menu
for( DWORD j=0; j<dwItems; j++ )
{
BOOL bButtonState = (rgdod[j].dwData==0x80) ? TRUE : FALSE;
FLOAT fButtonState = (rgdod[j].dwData==0x80) ? 1.0f : 0.0f;
FLOAT fAxisState = (FLOAT)((int)rgdod[j].dwData)/100.0f;
switch( rgdod[j].uAppData )
{
// Handle relative axis data
case INPUT_ROTATE_AXIS_LR:
pInputDeviceState->fAxisRotateLR = fAxisState;
break;
case INPUT_MOVE_AXIS_UD:
pInputDeviceState->fAxisMoveUD = -fAxisState;
break;
// Handle buttons separately so the button state data
// doesn't overwrite the axis state data, and handle
// each button separately so they don't overwrite each other
case INPUT_TURNLEFT: pInputDeviceState->bButtonRotateLeft = bButtonState; break;
case INPUT_TURNRIGHT: pInputDeviceState->bButtonRotateRight = bButtonState; break;
case INPUT_FORWARDTHRUST: pInputDeviceState->bButtonForwardThrust = bButtonState; break;
case INPUT_REVERSETHRUST: pInputDeviceState->bButtonReverseThrust = bButtonState; break;
case INPUT_FIREWEAPONS: pInputDeviceState->bButtonFireWeapons = bButtonState; break;
case INPUT_ENABLESHIELD: pInputDeviceState->bButtonEnableShield = bButtonState; break;
// Handle one-shot buttons
case INPUT_DISPLAYGAMEMENU: if( bButtonState ) pUserInput->bDoConfigureInput = TRUE; break;
case INPUT_QUITGAME: if( bButtonState ) pUserInput->bDoQuitGame = TRUE; break;
}
}
}
// Process user input and store result into pUserInput struct
pUserInput->fAxisRotateLR = 0.0f;
pUserInput->fAxisMoveUD = 0.0f;
pUserInput->bButtonFireWeapons = FALSE;
pUserInput->bButtonEnableShield = FALSE;
// Concatinate the data from all the DirectInput devices
for( i=0; i<dwNumDevices; i++ )
{
InputDeviceState* pInputDeviceState = (InputDeviceState*) pDeviceInfos[i].pParam;
// Use the axis data that is furthest from zero
if( fabs(pInputDeviceState->fAxisRotateLR) > fabs(pUserInput->fAxisRotateLR) )
pUserInput->fAxisRotateLR = pInputDeviceState->fAxisRotateLR;
if( fabs(pInputDeviceState->fAxisMoveUD) > fabs(pUserInput->fAxisMoveUD) )
pUserInput->fAxisMoveUD = pInputDeviceState->fAxisMoveUD;
// Process the button data
if( pInputDeviceState->bButtonRotateLeft )
pUserInput->fAxisRotateLR = -1.0f;
else if( pInputDeviceState->bButtonRotateRight )
pUserInput->fAxisRotateLR = 1.0f;
if( pInputDeviceState->bButtonForwardThrust )
pUserInput->fAxisMoveUD = 1.0f;
else if( pInputDeviceState->bButtonReverseThrust )
pUserInput->fAxisMoveUD = -1.0f;
if( pInputDeviceState->bButtonFireWeapons )
pUserInput->bButtonFireWeapons = TRUE;
if( pInputDeviceState->bButtonEnableShield )
pUserInput->bButtonEnableShield = TRUE;
}
}
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Called once per frame, the call is the entry point for rendering the
// world.
//-----------------------------------------------------------------------------
HRESULT CMyApplication::Render()
{
TCHAR szMsg[MAX_PATH];
TCHAR szMsgCurrent[MAX_PATH];
_stprintf( szMsg, TEXT("%0.2f"), m_UserInput.fAxisMoveUD );
GetWindowText( GetDlgItem(m_hWnd,IDC_UD_AXIS_STATE), szMsgCurrent, MAX_PATH );
if( lstrcmp( szMsgCurrent, szMsg ) != 0 )
SetWindowText( GetDlgItem(m_hWnd,IDC_UD_AXIS_STATE), szMsg );
_stprintf( szMsg, TEXT("%0.2f"), m_UserInput.fAxisRotateLR );
GetWindowText( GetDlgItem(m_hWnd,IDC_LR_AXIS_STATE), szMsgCurrent, MAX_PATH );
if( lstrcmp( szMsgCurrent, szMsg ) != 0 )
SetWindowText( GetDlgItem(m_hWnd,IDC_LR_AXIS_STATE), szMsg );
if( !m_UserInput.bButtonEnableShield && !m_UserInput.bButtonFireWeapons )
{
_stprintf( szMsg, TEXT("None") );
}
else
{
_stprintf( szMsg, TEXT("%s%s"), m_UserInput.bButtonEnableShield ? TEXT("Shield ") : TEXT(""),
m_UserInput.bButtonFireWeapons ? TEXT("Fire ") : TEXT("") );
}
GetWindowText( GetDlgItem(m_hWnd,IDC_BUTTON_STATE), szMsgCurrent, MAX_PATH );
if( lstrcmp( szMsgCurrent, szMsg ) != 0 )
SetWindowText( GetDlgItem(m_hWnd,IDC_BUTTON_STATE), szMsg );
_stprintf( szMsg, TEXT("%0.3f, %0.3f"), m_fWorldRotX, m_fWorldRotY );
GetWindowText( GetDlgItem(m_hWnd,IDC_WORLD_STATE), szMsgCurrent, MAX_PATH );
if( lstrcmp( szMsgCurrent, szMsg ) != 0 )
SetWindowText( GetDlgItem(m_hWnd,IDC_WORLD_STATE), szMsg );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: StaticMsgProc()
// Desc: Static msg handler which passes messages to the application class.
//-----------------------------------------------------------------------------
INT_PTR CALLBACK StaticMsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
return g_pApp->MsgProc( hWnd, uMsg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: Callback for all Windows messages
//-----------------------------------------------------------------------------
INT_PTR CMyApplication::MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
HRESULT hr;
switch( msg )
{
case WM_INITDIALOG:
m_hWnd = hWnd;
// Initialize the app's custom scene stuff
if( FAILED( hr = OneTimeSceneInit() ) )
{
DXTRACE_ERR( TEXT("OneTimeSceneInit"), hr );
MessageBox( hWnd, TEXT("Error initializing DirectInput. Sample will now exit."),
TEXT("DirectInput Sample"), MB_OK | MB_ICONERROR );
PostQuitMessage( IDCANCEL );
return TRUE;
}
break;
case WM_COMMAND:
{
switch( LOWORD(wParam) )
{
case IDCANCEL:
PostQuitMessage( IDCANCEL );
break;
case IDM_CONFIGINPUT:
m_UserInput.bDoConfigureInput = TRUE;
break;
}
break;
}
}
return FALSE;
}
//-----------------------------------------------------------------------------
// Name: FinalCleanup()
// Desc: Called before the app exits, this function gives the app the chance
// to cleanup after itself.
//-----------------------------------------------------------------------------
HRESULT CMyApplication::FinalCleanup()
{
// Cleanup DirectInput
CleanupDirectInput();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CleanupDirectInput()
// Desc: Cleanup DirectInput
//-----------------------------------------------------------------------------
VOID CMyApplication::CleanupDirectInput()
{
if( NULL == m_pInputDeviceManager )
return;
// Get access to the list of semantically-mapped input devices
// to delete all InputDeviceState structs
CInputDeviceManager::DeviceInfo* pDeviceInfos;
DWORD dwNumDevices;
m_pInputDeviceManager->GetDevices( &pDeviceInfos, &dwNumDevices );
for( DWORD i=0; i<dwNumDevices; i++ )
{
InputDeviceState* pInputDeviceState = (InputDeviceState*) pDeviceInfos[i].pParam;
SAFE_DELETE( pInputDeviceState );
pDeviceInfos[i].pParam = NULL;
}
// Cleanup DirectX input objects
SAFE_DELETE( m_pInputDeviceManager );
}

View File

@@ -0,0 +1,183 @@
# Microsoft Developer Studio Project File - Name="ActionMapper" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=ActionMapper - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ActionMapper.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ActionMapper.mak" CFG="ActionMapper - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ActionMapper - Win32 Release Unicode" (based on "Win32 (x86) Application")
!MESSAGE "ActionMapper - Win32 Debug Unicode" (based on "Win32 (x86) Application")
!MESSAGE "ActionMapper - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "ActionMapper - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "ActionMapper - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\common\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 dsound.lib dinput8.lib dxerr8.lib d3dx8dt.lib d3d8.lib d3dxof.lib dxguid.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 dsound.lib dinput8.lib dxerr8.lib d3dx8dt.lib d3d8.lib d3dxof.lib dxguid.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /stack:0x200000,0x200000 /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "ActionMapper - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\common\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 dsound.lib dinput8.lib dxerr8.lib d3dx8dt.lib d3d8.lib d3dxof.lib dxguid.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 dsound.lib dinput8.lib dxerr8.lib d3dx8dt.lib d3d8.lib d3dxof.lib dxguid.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /stack:0x200000,0x200000 /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ELSEIF "$(CFG)" == "ActionMapper - Win32 Release Unicode"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "ActionMapper___Win32_Release_Unicode"
# PROP BASE Intermediate_Dir "ActionMapper___Win32_Release_Unicode"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "ActionMapper___Win32_Release_Unicode"
# PROP Intermediate_Dir "ActionMapper___Win32_Release_Unicode"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\common\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\common\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "UNICODE" /D "_UNICODE" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 dsound.lib dinput8.lib dxerr8.lib d3dx8dt.lib d3d8.lib d3dxof.lib dxguid.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /stack:0x200000,0x200000 /subsystem:windows /machine:I386
# ADD LINK32 dsound.lib dinput8.lib dxerr8.lib d3dx8dt.lib d3d8.lib d3dxof.lib dxguid.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /stack:0x200000,0x200000 /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "ActionMapper - Win32 Debug Unicode"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "ActionMapper___Win32_Debug_Unicode"
# PROP BASE Intermediate_Dir "ActionMapper___Win32_Debug_Unicode"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "ActionMapper___Win32_Debug_Unicode"
# PROP Intermediate_Dir "ActionMapper___Win32_Debug_Unicode"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\common\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\common\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "UNICODE" /D "_UNICODE" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 dsound.lib dinput8.lib dxerr8.lib d3dx8dt.lib d3d8.lib d3dxof.lib dxguid.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /stack:0x200000,0x200000 /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 dsound.lib dinput8.lib dxerr8.lib d3dx8dt.lib d3d8.lib d3dxof.lib dxguid.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /stack:0x200000,0x200000 /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "ActionMapper - Win32 Release"
# Name "ActionMapper - Win32 Debug"
# Name "ActionMapper - Win32 Release Unicode"
# Name "ActionMapper - Win32 Debug Unicode"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\ActionMapper.cpp
# End Source File
# Begin Source File
SOURCE=.\ActionMapper.rc
# End Source File
# Begin Source File
SOURCE=.\DirectX.ico
# End Source File
# Begin Source File
SOURCE=.\resource.h
# End Source File
# End Group
# Begin Group "Common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\common\src\diutil.cpp
# End Source File
# Begin Source File
SOURCE=..\..\common\include\diutil.h
# End Source File
# Begin Source File
SOURCE=..\..\common\src\dxutil.cpp
# End Source File
# Begin Source File
SOURCE=..\..\common\include\dxutil.h
# End Source File
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "ActionMapper"=.\ActionMapper.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -0,0 +1,221 @@
# Microsoft Developer Studio Generated NMAKE File, Based on actionmapper.dsp
!IF "$(CFG)" == ""
CFG=ActionMapper - Win32 Debug
!MESSAGE No configuration specified. Defaulting to ActionMapper - Win32 Debug.
!ENDIF
!IF "$(CFG)" != "ActionMapper - Win32 Release" && "$(CFG)" != "ActionMapper - Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "actionmapper.mak" CFG="ActionMapper - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ActionMapper - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "ActionMapper - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE
NULL=nul
!ENDIF
!IF "$(CFG)" == "ActionMapper - Win32 Release"
OUTDIR=.\Release
INTDIR=.\Release
# Begin Custom Macros
OutDir=.\Release
# End Custom Macros
ALL : "$(OUTDIR)\actionmapper.exe"
CLEAN :
-@erase "$(INTDIR)\ActionMapper.obj"
-@erase "$(INTDIR)\ActionMapper.res"
-@erase "$(INTDIR)\diutil.obj"
-@erase "$(INTDIR)\dxutil.obj"
-@erase "$(INTDIR)\vc60.idb"
-@erase "$(OUTDIR)\actionmapper.exe"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP=cl.exe
CPP_PROJ=/nologo /ML /W3 /GX /O2 /I "..\..\common\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Fp"$(INTDIR)\actionmapper.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.c{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
MTL=midl.exe
MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
RSC=rc.exe
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\ActionMapper.res" /d "NDEBUG"
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\actionmapper.bsc"
BSC32_SBRS= \
LINK32=link.exe
LINK32_FLAGS=dsound.lib dinput8.lib dxerr8.lib d3dx8dt.lib d3d8.lib d3dxof.lib dxguid.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\actionmapper.pdb" /machine:I386 /out:"$(OUTDIR)\actionmapper.exe" /stack:0x200000,0x200000
LINK32_OBJS= \
"$(INTDIR)\ActionMapper.obj" \
"$(INTDIR)\diutil.obj" \
"$(INTDIR)\dxutil.obj" \
"$(INTDIR)\ActionMapper.res"
"$(OUTDIR)\actionmapper.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "ActionMapper - Win32 Debug"
OUTDIR=.\Debug
INTDIR=.\Debug
# Begin Custom Macros
OutDir=.\Debug
# End Custom Macros
ALL : "$(OUTDIR)\actionmapper.exe"
CLEAN :
-@erase "$(INTDIR)\ActionMapper.obj"
-@erase "$(INTDIR)\ActionMapper.res"
-@erase "$(INTDIR)\diutil.obj"
-@erase "$(INTDIR)\dxutil.obj"
-@erase "$(INTDIR)\vc60.idb"
-@erase "$(INTDIR)\vc60.pdb"
-@erase "$(OUTDIR)\actionmapper.exe"
-@erase "$(OUTDIR)\actionmapper.ilk"
-@erase "$(OUTDIR)\actionmapper.pdb"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP=cl.exe
CPP_PROJ=/nologo /MLd /W3 /Gm /GX /ZI /Od /I "..\..\common\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Fp"$(INTDIR)\actionmapper.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.c{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
MTL=midl.exe
MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
RSC=rc.exe
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\ActionMapper.res" /d "_DEBUG"
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\actionmapper.bsc"
BSC32_SBRS= \
LINK32=link.exe
LINK32_FLAGS=dsound.lib dinput8.lib dxerr8.lib d3dx8dt.lib d3d8.lib d3dxof.lib dxguid.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\actionmapper.pdb" /debug /machine:I386 /out:"$(OUTDIR)\actionmapper.exe" /pdbtype:sept /stack:0x200000,0x200000
LINK32_OBJS= \
"$(INTDIR)\ActionMapper.obj" \
"$(INTDIR)\diutil.obj" \
"$(INTDIR)\dxutil.obj" \
"$(INTDIR)\ActionMapper.res"
"$(OUTDIR)\actionmapper.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
!IF "$(NO_EXTERNAL_DEPS)" != "1"
!IF EXISTS("actionmapper.dep")
!INCLUDE "actionmapper.dep"
!ELSE
!MESSAGE Warning: cannot find "actionmapper.dep"
!ENDIF
!ENDIF
!IF "$(CFG)" == "ActionMapper - Win32 Release" || "$(CFG)" == "ActionMapper - Win32 Debug"
SOURCE=.\ActionMapper.cpp
"$(INTDIR)\ActionMapper.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\ActionMapper.rc
"$(INTDIR)\ActionMapper.res" : $(SOURCE) "$(INTDIR)"
$(RSC) $(RSC_PROJ) $(SOURCE)
SOURCE=..\..\common\src\diutil.cpp
"$(INTDIR)\diutil.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=..\..\common\src\dxutil.cpp
"$(INTDIR)\dxutil.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
!ENDIF

View File

@@ -0,0 +1,23 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by ActionMapper.rc
//
#define IDI_MAIN_ICON 101
#define IDD_MAIN 101
#define IDC_UD_AXIS_STATE 1031
#define IDC_LR_AXIS_STATE 1032
#define IDC_WORLD_STATE 1033
#define IDC_BUTTON_STATE 1034
#define IDM_CONFIGINPUT 40011
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 146
#define _APS_NEXT_COMMAND_VALUE 40013
#define _APS_NEXT_CONTROL_VALUE 1035
#define _APS_NEXT_SYMED_VALUE 102
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

View File

@@ -0,0 +1,155 @@
//-----------------------------------------------------------------------------
// File: bidirlookup.h
//
// Desc: This file implements a bi-directional map class template. It does
// this by using two CMap classes that each handles the look up in one
// direction.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __BIDIRLOOKUP_H__
#define __BIDIRLOOKUP_H__
#ifndef NULL
#define NULL 0
#endif
template <class L, class R>
class bidirlookup
{
private:
CMap<L, const L &, R, const R &> l2r;
CMap<R, const R &, L, const L &> r2l;
bool addnode(const L &l, const R &r)
{
l2r.SetAt(l, r);
r2l.SetAt(r, l);
return true;
}
public:
void clear()
{
l2r.RemoveAll();
r2l.RemoveAll();
}
bidirlookup() {}
~bidirlookup() {clear();}
bool add(const L &l, const R &r)
{
L tl;
R tr;
if (l2r.Lookup(l, tr) || r2l.Lookup(r, tl))
return false;
return addnode(l, r);
}
bool getleft(L &l, const R &r)
{
return r2l.Lookup(r, l) ? true : false;
}
bool getright(const L &l, R &r)
{
return l2r.Lookup(l, r) ? true : false;
}
};
#if 0
template <class L, class R>
class bidirlookup
{
private:
struct node {
node(const L &a, const R &b) : l(a), r(b), next(NULL) {}
node *next;
L l;
R r;
} *head;
bool addnode(const L &l, const R &r)
{
node *old = head;
head = new node(l, r);
if (!head)
return false;
head->next = old;
return true;
}
node *getleftnode(const L &l)
{
for (node *on = head; on; on = on->next)
if (on->l == l)
return on;
return NULL;
}
node *getrightnode(const R &r)
{
for (node *on = head; on; on = on->next)
if (on->r == r)
return on;
return NULL;
}
public:
void clear()
{
while (head)
{
node *next = head->next;
delete head;
head = next;
}
}
bidirlookup() : head(NULL) {}
~bidirlookup() {clear();}
bool add(const L &l, const R &r)
{
if (getleftnode(l) || getrightnode(r))
return false;
return addnode(l, r);
}
bool getleft(L &l, const R &r)
{
node *n = getrightnode(r);
if (!n)
return false;
l = n->l;
return true;
}
bool getright(const L &l, R &r)
{
node *n = getleftnode(l);
if (!n)
return false;
r = n->r;
return true;
}
};
#endif
#endif //__BIDIRLOOKUP_H__

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

View File

@@ -0,0 +1,726 @@
//-----------------------------------------------------------------------------
// File: Cbitmap.cpp
//
// Desc: CBitmap class is an object that wraps around a Windows bitmap.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
#include "id3dsurf.h"
BOOL DI_AlphaBlend(
HDC hdcDest, // handle to destination DC
int nXOriginDest, // x-coord of upper-left corner
int nYOriginDest, // y-coord of upper-left corner
int nWidthDest, // destination width
int nHeightDest, // destination height
HDC hdcSrc, // handle to source DC
int nXOriginSrc, // x-coord of upper-left corner
int nYOriginSrc, // y-coord of upper-left corner
int nWidthSrc, // source width
int nHeightSrc // source height
)
{
LPBYTE pbDestBits = NULL;
HBITMAP hTempDestDib = NULL;
int nXOriginDestLogical = nXOriginDest, nYOriginDestLogical = nYOriginDest;
// Convert nXOriginDest and nYOriginDest from logical coord to device coord
POINT pt = {nXOriginDest, nYOriginDest};
LPtoDP(hdcDest, &pt, 1);
nXOriginDest = pt.x;
nYOriginDest = pt.y;
// Convert nXOriginSrc and nYOriginSrc from logical coord to device coord
pt.x = nXOriginSrc;
pt.y = nYOriginSrc;
LPtoDP(hdcSrc, &pt, 1);
nXOriginSrc = pt.x;
nYOriginSrc = pt.y;
// Get the bits for both source and destination first
// Every BITMAP used in the UI is created with CreateDIBSection, so we know we can get the bits.
HBITMAP hSrcBmp, hDestBmp;
DIBSECTION SrcDibSec, DestDibSec;
hSrcBmp = (HBITMAP)GetCurrentObject(hdcSrc, OBJ_BITMAP);
GetObject(hSrcBmp, sizeof(DIBSECTION), &SrcDibSec);
hDestBmp = (HBITMAP)GetCurrentObject(hdcDest, OBJ_BITMAP);
GetObject(hDestBmp, sizeof(DIBSECTION), &DestDibSec);
if (!SrcDibSec.dsBm.bmBits) return FALSE; // Not necessary, but to be absolutely safe.
// Calculate the rectangle to perform the operation.
if (nXOriginSrc + nWidthSrc > SrcDibSec.dsBm.bmWidth) nWidthSrc = SrcDibSec.dsBm.bmWidth - nXOriginSrc;
if (nYOriginSrc + nHeightSrc > SrcDibSec.dsBm.bmHeight) nHeightSrc = SrcDibSec.dsBm.bmHeight - nYOriginSrc;
if (nXOriginDest + nWidthDest > DestDibSec.dsBm.bmWidth) nWidthDest = DestDibSec.dsBm.bmWidth - nXOriginDest;
if (nYOriginDest + nHeightDest > DestDibSec.dsBm.bmHeight) nHeightDest = DestDibSec.dsBm.bmHeight - nYOriginDest;
if (nWidthDest > nWidthSrc) nWidthDest = nWidthSrc;
if (nHeightDest > nHeightSrc) nHeightDest = nHeightSrc;
if (nWidthSrc > nWidthDest) nWidthSrc = nWidthDest;
if (nHeightSrc > nHeightDest) nHeightSrc = nHeightDest;
BITMAPINFO bmi;
ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = nWidthDest;
bmi.bmiHeader.biHeight = nHeightDest;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
// Bitmap will have the same width as the dest, but only lines covered in the subrect.
hTempDestDib = CreateDIBSection(hdcDest, &bmi, DIB_RGB_COLORS, (LPVOID*)&pbDestBits, NULL, NULL);
if (!hTempDestDib)
return FALSE;
HDC hTempDC = CreateCompatibleDC(hdcDest);
if (!hTempDC)
{
DeleteObject(hTempDestDib);
return FALSE;
}
HBITMAP hOldTempBmp = (HBITMAP)SelectObject(hTempDC, hTempDestDib);
BOOL res = BitBlt(hTempDC, 0, 0, nWidthDest, nHeightDest, hdcDest, nXOriginDestLogical, nYOriginDestLogical, SRCCOPY);
SelectObject(hTempDC, hOldTempBmp);
DeleteDC(hTempDC);
if (!res)
{
DeleteObject(hTempDestDib);
return FALSE;
}
// We have the bits. Now do the blend.
for (int j = 0; j < nHeightSrc; ++j)
{
assert(j >= 0 &&
j < nHeightDest);
LPBYTE pbDestRGB = (LPBYTE)&((DWORD*)pbDestBits)[j * nWidthDest];
assert(nYOriginSrc+SrcDibSec.dsBm.bmHeight-nHeightSrc >= 0 &&
nYOriginSrc+SrcDibSec.dsBm.bmHeight-nHeightSrc < SrcDibSec.dsBm.bmHeight);
LPBYTE pbSrcRGBA = (LPBYTE)&((DWORD*)SrcDibSec.dsBm.bmBits)[(j+nYOriginSrc+SrcDibSec.dsBm.bmHeight-nHeightSrc)
* SrcDibSec.dsBm.bmWidth + nXOriginSrc];
for (int i = 0; i < nWidthSrc; ++i)
{
// Blend
if (pbSrcRGBA[3] == 255)
{
// Alpha is 255. straight copy.
*(LPDWORD)pbDestRGB = *(LPDWORD)pbSrcRGBA;
} else
if (pbSrcRGBA[3])
{
// Alpha is non-zero
pbDestRGB[0] = pbSrcRGBA[0] + (((255-pbSrcRGBA[3]) * pbDestRGB[0]) >> 8);
pbDestRGB[1] = pbSrcRGBA[1] + (((255-pbSrcRGBA[3]) * pbDestRGB[1]) >> 8);
pbDestRGB[2] = pbSrcRGBA[2] + (((255-pbSrcRGBA[3]) * pbDestRGB[2]) >> 8);
}
pbDestRGB += sizeof(DWORD);
pbSrcRGBA += sizeof(DWORD);
} // for
} // for
HDC hdcTempDest = CreateCompatibleDC(hdcDest);
if (hdcTempDest)
{
HBITMAP hOldTempBmp = (HBITMAP)SelectObject(hdcTempDest, hTempDestDib); // Select the temp dib for blitting
// Get logical coord for device coord of dest origin
POINT pt = {nXOriginDest, nYOriginDest};
DPtoLP(hdcDest, &pt, 1);
BitBlt(hdcDest, pt.x, pt.y, nWidthDest, nHeightDest,
hdcTempDest, 0, 0, SRCCOPY);
SelectObject(hdcTempDest, hOldTempBmp);
DeleteDC(hdcTempDest);
}
DeleteObject(hTempDestDib);
return TRUE;
}
CBitmap::~CBitmap()
{
if (m_hbm != NULL)
DeleteObject(m_hbm);
m_hbm = NULL;
m_bSizeKnown = FALSE;
}
HDC CreateAppropDC(HDC hDC)
{
return CreateCompatibleDC(hDC);
}
HBITMAP CreateAppropBitmap(HDC hDC, int cx, int cy)
{
if (hDC != NULL)
return CreateCompatibleBitmap(hDC, cx, cy);
HWND hWnd = GetDesktopWindow();
HDC hWDC = GetWindowDC(hWnd);
HBITMAP hbm = NULL;
if (hWDC != NULL)
{
hbm = CreateCompatibleBitmap(hWDC, cx, cy);
ReleaseDC(hWnd, hWDC);
}
return hbm;
}
CBitmap *CBitmap::CreateFromResource(HINSTANCE hInst, LPCTSTR tszName)
{
return CreateViaLoadImage(hInst, tszName, IMAGE_BITMAP, 0, 0,
LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
}
CBitmap *CBitmap::CreateFromFile(LPCTSTR tszFileName)
{
return CreateViaD3DX(tszFileName);
}
// Use D3DX API to load our surface with image content.
CBitmap *CBitmap::CreateViaD3DX(LPCTSTR tszFileName, LPDIRECT3DSURFACE8 pUISurf)
{
HRESULT hr;
LPDIRECT3DDEVICE8 pD3DDev = NULL;
LPDIRECT3DTEXTURE8 pTex = NULL;
LPDIRECT3DSURFACE8 pSurf = NULL;
HBITMAP hDIB = NULL;
CBitmap *pbm = NULL;
// If the UI surface is NULL, create a new device. Otherwise, use existing device.
if (!pUISurf)
{
LPDIRECT3D8 pD3D = Direct3DCreate8(D3D_SDK_VERSION);
if (!pD3D)
{
OutputDebugString(_T("Failed to create D3D\n"));
hr = E_FAIL;
}
else
{
D3DDISPLAYMODE Mode;
pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Mode);
D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = 1;
d3dpp.BackBufferHeight = 1;
d3dpp.BackBufferFormat = Mode.Format;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
d3dpp.hDeviceWindow = NULL;
d3dpp.Windowed = TRUE;
d3dpp.EnableAutoDepthStencil = FALSE;
d3dpp.FullScreen_RefreshRateInHz = 0;
d3dpp.FullScreen_PresentationInterval = 0;
d3dpp.Flags = 0;
hr = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, GetActiveWindow(), D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pD3DDev);
if (FAILED(hr))
{
TCHAR tszMsg[MAX_PATH];
_stprintf(tszMsg, _T("CreateDevice returned 0x%X\n"), hr);
OutputDebugString(tszMsg);
}
pD3D->Release();
}
}
else
{
hr = pUISurf->GetDevice(&pD3DDev);
}
if( FAILED( hr ) )
{
OutputDebugString(_T("Failed to create D3D device\n"));
}
else if( FAILED( hr = pD3DDev->CreateTexture(512, 512, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pTex) ) )
{
OutputDebugString(_T("Failed to create D3D texture\n"));
}
else if( FAILED( hr = pTex->GetSurfaceLevel(0, &pSurf) ) )
{
OutputDebugString(_T("Failed to obtain surface interface\n"));
}
else
{
D3DXIMAGE_INFO d3dii;
if( SUCCEEDED( D3DXLoadSurfaceFromFile(pSurf, NULL, NULL, tszFileName, NULL, D3DX_FILTER_NONE, 0, &d3dii) ) )
{
// Create a bitmap and copy the texture content onto it.
int iDibWidth = d3dii.Width, iDibHeight = d3dii.Height;
if (iDibWidth > 430) iDibWidth = 430;
if (iDibHeight > 310) iDibHeight = 310;
LPBYTE pDIBBits;
BITMAPINFO bmi;
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
bmi.bmiHeader.biWidth = iDibWidth;
bmi.bmiHeader.biHeight = iDibHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
hDIB = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (LPVOID*)&pDIBBits, NULL, 0);
if (hDIB)
{
// Pre-process the pixel data based on alpha for AlphaBlend()
D3DLOCKED_RECT lrc;
pSurf->LockRect(&lrc, NULL, NULL);
BYTE *pbData = (LPBYTE)lrc.pBits;
{
for (DWORD i = 0; i < 512 * 512; ++i)
{
BYTE bAlpha = pbData[i * 4 + 3];
pbData[i * 4] = pbData[i * 4] * bAlpha / 255;
pbData[i * 4 + 1] = pbData[i * 4 + 1] * bAlpha / 255;
pbData[i * 4 + 2] = pbData[i * 4 + 2] * bAlpha / 255;
}
}
pSurf->UnlockRect();
// Lock the surface
D3DLOCKED_RECT D3DRect;
hr = pSurf->LockRect(&D3DRect, NULL, 0);
if (SUCCEEDED(hr))
{
// Copy the bits
// Note that the image is reversed in Y direction, so we need to re-reverse it.
for (int y = 0; y < iDibHeight; ++y)
CopyMemory(pDIBBits + ((iDibHeight-1-y) * iDibWidth * 4), (LPBYTE)D3DRect.pBits + (y * D3DRect.Pitch), iDibWidth * 4);
// Unlock
pSurf->UnlockRect();
pbm = new CBitmap;
if (pbm)
{
pbm->m_hbm = hDIB;
hDIB = NULL;
pbm->FigureSize();
}
}
}
}
}
if (hDIB) DeleteObject(hDIB);
if (pSurf) pSurf->Release();
if (pTex) pTex->Release();
if (pD3DDev) pD3DDev->Release();
return pbm;
}
CBitmap *CBitmap::CreateViaLoadImage(HINSTANCE hInst, LPCTSTR tszName, UINT uType, int cx, int cy, UINT fuLoad)
{
if (fuLoad & LR_SHARED)
{
assert(0);
return NULL;
}
CBitmap *pbm = new CBitmap;
if (pbm == NULL)
return NULL;
HANDLE handle = ::LoadImage(hInst, tszName, uType, cx, cy, fuLoad);
if (handle == NULL)
{
delete pbm;
return NULL;
}
pbm->m_hbm = (HBITMAP)handle;
pbm->FigureSize();
return pbm;
}
BOOL CBitmap::FigureSize()
{
BITMAP bm;
if (0 == GetObject((HGDIOBJ)m_hbm, sizeof(BITMAP), (LPVOID)&bm))
return FALSE;
m_size.cx = abs(bm.bmWidth);
m_size.cy = abs(bm.bmHeight);
return m_bSizeKnown = TRUE;
}
CBitmap *CBitmap::StealToCreate(HBITMAP &refbm)
{
if (refbm == NULL)
return NULL;
CBitmap *pbm = new CBitmap;
if (pbm == NULL)
return NULL;
pbm->m_hbm = refbm;
refbm = NULL;
pbm->FigureSize();
return pbm;
}
BOOL CBitmap::GetSize(SIZE *psize)
{
if (m_hbm == NULL || !m_bSizeKnown || psize == NULL)
return FALSE;
*psize = m_size;
return TRUE;
}
void CBitmap::AssumeSize(SIZE size)
{
m_size = size;
m_bSizeKnown = TRUE; //m_hbm != NULL;
}
CBitmap *CBitmap::CreateResizedTo(SIZE size, HDC hDC, int iStretchMode, BOOL bStretch)
{
CBitmap *pbm = new CBitmap;
HDC hSrcDC = NULL;
HDC hDestDC = NULL;
HBITMAP hBitmap = NULL;
HGDIOBJ hOldSrcBitmap = NULL, hOldDestBitmap = NULL;
BOOL bRet = FALSE;
int oldsm = 0;
POINT brushorg;
if (pbm == NULL || size.cx < 1 || size.cy < 1 || m_hbm == NULL || !m_bSizeKnown)
goto error;
hSrcDC = CreateAppropDC(hDC);
hDestDC = CreateAppropDC(hDC);
if (hSrcDC == NULL || hDestDC == NULL)
goto error;
hBitmap = CreateAppropBitmap(hDC, size.cx, size.cy);
if (hBitmap == NULL)
goto error;
if (bStretch)
{
if (GetStretchBltMode(hDestDC) != iStretchMode)
{
if (iStretchMode == HALFTONE)
GetBrushOrgEx(hDestDC, &brushorg);
oldsm = SetStretchBltMode(hDestDC, iStretchMode);
if (iStretchMode == HALFTONE)
SetBrushOrgEx(hDestDC, brushorg.x, brushorg.y, NULL);
}
}
hOldSrcBitmap = SelectObject(hSrcDC, m_hbm);
hOldDestBitmap = SelectObject(hDestDC, hBitmap);
if (bStretch)
bRet = StretchBlt(hDestDC, 0, 0, size.cx, size.cy, hSrcDC, 0, 0, m_size.cx, m_size.cy, SRCCOPY);
else
bRet = BitBlt(hDestDC, 0, 0, size.cx, size.cy, hSrcDC, 0, 0, SRCCOPY);
SelectObject(hDestDC, hOldDestBitmap);
SelectObject(hSrcDC, hOldSrcBitmap);
if (bStretch)
{
if (oldsm != 0)
{
if (oldsm == HALFTONE)
GetBrushOrgEx(hDestDC, &brushorg);
SetStretchBltMode(hDestDC, oldsm);
if (oldsm == HALFTONE)
SetBrushOrgEx(hDestDC, brushorg.x, brushorg.y, NULL);
}
}
if (!bRet)
goto error;
pbm->m_hbm = hBitmap;
hBitmap = NULL;
pbm->AssumeSize(size);
goto cleanup;
error:
if (pbm != NULL)
delete pbm;
pbm = NULL;
cleanup:
if (hBitmap != NULL)
DeleteObject(hBitmap);
if (hSrcDC != NULL)
DeleteDC(hSrcDC);
if (hDestDC != NULL)
DeleteDC(hDestDC);
return pbm;
}
HDC CBitmap::BeginPaintInto(HDC hCDC)
{
if (m_hDCInto != NULL)
{
assert(0);
return NULL;
}
m_hDCInto = CreateAppropDC(hCDC);
if (m_hDCInto == NULL)
return NULL;
m_hOldBitmap = SelectObject(m_hDCInto, m_hbm);
return m_hDCInto;
}
void CBitmap::EndPaintInto(HDC &hDC)
{
if (hDC == NULL || hDC != m_hDCInto)
{
assert(0);
return;
}
SelectObject(m_hDCInto, m_hOldBitmap);
DeleteDC(m_hDCInto);
m_hDCInto = NULL;
hDC = NULL;
}
void CBitmap::PopOut()
{
if (m_hDCInto == NULL)
{
assert(0);
return;
}
SelectObject(m_hDCInto, m_hOldBitmap);
}
void CBitmap::PopIn()
{
if (m_hDCInto == NULL)
{
assert(0);
return;
}
m_hOldBitmap = SelectObject(m_hDCInto, m_hbm);
}
BOOL CBitmap::Draw(HDC hDC, POINT origin, SIZE crop, BOOL bAll)
{
if (hDC == NULL || m_hbm == NULL)
return FALSE;
if (bAll && !m_bSizeKnown)
return FALSE;
if (bAll)
crop = m_size;
HDC hDCbm = CreateAppropDC(hDC);
if (hDCbm == NULL)
return FALSE;
BOOL bPop = m_hDCInto != NULL;
if (bPop)
PopOut();
HGDIOBJ hOldBitmap = SelectObject(hDCbm, m_hbm);
BOOL bRet = BitBlt(hDC, origin.x, origin.y, crop.cx, crop.cy, hDCbm, 0, 0, SRCCOPY);
SelectObject(hDCbm, hOldBitmap);
DeleteDC(hDCbm);
if (bPop)
PopIn();
return bRet;
}
BOOL CBitmap::Blend(HDC hDC, POINT origin, SIZE crop, BOOL bAll)
{
if (hDC == NULL || m_hbm == NULL)
return FALSE;
if (bAll && !m_bSizeKnown)
return FALSE;
if (bAll)
crop = m_size;
HDC hDCbm = CreateAppropDC(hDC);
if (hDCbm == NULL)
return FALSE;
BOOL bPop = m_hDCInto != NULL;
if (bPop)
PopOut();
#ifndef AC_SRC_ALPHA
#define AC_SRC_ALPHA AC_SRC_NO_PREMULT_ALPHA
#endif
HGDIOBJ hOldBitmap = SelectObject(hDCbm, m_hbm);
BOOL bRet;
bRet = DI_AlphaBlend(hDC, origin.x, origin.y, crop.cx, crop.cy, hDCbm, 0, 0, m_size.cx, m_size.cy);
SelectObject(hDCbm, hOldBitmap);
DeleteDC(hDCbm);
if (bPop)
PopIn();
return bRet;
}
CBitmap *CBitmap::Dup()
{
SIZE t;
if (!GetSize(&t))
return NULL;
return CreateResizedTo(t, NULL, COLORONCOLOR, FALSE);
}
CBitmap *CBitmap::Create(SIZE size, HDC hCDC)
{
CBitmap *pbm = new CBitmap;
if (pbm == NULL)
return NULL;
pbm->m_hbm = CreateAppropBitmap(hCDC, size.cx, size.cy);
if (pbm->m_hbm == NULL)
{
delete pbm;
return NULL;
}
pbm->AssumeSize(size);
return pbm;
}
CBitmap *CBitmap::Create(SIZE size, COLORREF color, HDC hCDC)
{
CBitmap *pbm = Create(size, hCDC);
if (pbm == NULL)
return NULL;
HDC hDC = pbm->BeginPaintInto();
if (hDC == NULL)
{
delete pbm;
return NULL;
}
HGDIOBJ hBrush = (HGDIOBJ)CreateSolidBrush(color), hOldBrush;
if (hBrush)
{
hOldBrush = SelectObject(hDC, hBrush);
Rectangle(hDC, -1, -1, size.cx + 1, size.cy + 1);
SelectObject(hDC, hOldBrush);
DeleteObject(hBrush);
}
pbm->EndPaintInto(hDC);
return pbm;
}
BOOL CBitmap::Get(HDC hDC, POINT point)
{
if (!m_bSizeKnown)
return FALSE;
return Get(hDC, point, m_size);
}
BOOL CBitmap::Get(HDC hDC, POINT point, SIZE size)
{
if (m_hDCInto != NULL || hDC == NULL)
return FALSE;
HDC hDCInto = BeginPaintInto(hDC);
if (hDCInto == NULL)
return FALSE;
BOOL bRet = BitBlt(hDCInto, 0, 0, size.cx, size.cy, hDC, point.x, point.y, SRCCOPY);
EndPaintInto(hDCInto);
return bRet;
}
CBitmap *CBitmap::CreateHorzGradient(const RECT &rect, COLORREF rgbLeft, COLORREF rgbRight)
{
SIZE size = GetRectSize(rect);
COLORREF rgbMid = RGB(
(int(GetRValue(rgbLeft)) + int(GetRValue(rgbRight))) / 2,
(int(GetGValue(rgbLeft)) + int(GetGValue(rgbRight))) / 2,
(int(GetBValue(rgbLeft)) + int(GetBValue(rgbRight))) / 2);
return Create(size, rgbMid);
}
BOOL CBitmap::MapToDC(HDC hDCTo, HDC hDCMapFrom)
{
if (hDCTo == NULL || !m_bSizeKnown || m_hDCInto != NULL)
return FALSE;
HBITMAP hbm = CreateAppropBitmap(hDCTo, m_size.cx, m_size.cy);
if (hbm == NULL)
return FALSE;
HDC hDCFrom = NULL;
HDC hDCInto = NULL;
HGDIOBJ hOld = NULL;
BOOL bRet = FALSE;
hDCFrom = BeginPaintInto(hDCMapFrom);
if (!hDCFrom)
goto cleanup;
hDCInto = CreateCompatibleDC(hDCTo);
if (!hDCInto)
goto cleanup;
hOld = SelectObject(hDCInto, (HGDIOBJ)hbm);
bRet = BitBlt(hDCInto, 0, 0, m_size.cx, m_size.cy, hDCFrom, 0, 0, SRCCOPY);
SelectObject(hDCInto, hOld);
cleanup:
if (hDCFrom)
EndPaintInto(hDCFrom);
if (hDCInto)
DeleteDC(hDCInto);
if (bRet)
{
if (m_hbm)
DeleteObject((HGDIOBJ)m_hbm);
m_hbm = hbm;
hbm = NULL;
}
if (hbm)
DeleteObject((HGDIOBJ)hbm);
return bRet;
}

View File

@@ -0,0 +1,75 @@
//-----------------------------------------------------------------------------
// File: Cbitmap.h
//
// Desc: CBitmap class is an object that wraps around a Windows bitmap.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __CBITMAP_H__
#define __CBITMAP_H__
class CBitmap
{
private:
CBitmap() :
m_hbm(NULL),
m_bSizeKnown(FALSE),
m_hDCInto(NULL), m_hOldBitmap(NULL)
{}
public:
~CBitmap();
static CBitmap *CreateViaD3DX(LPCTSTR tszFileName, LPDIRECT3DSURFACE8 pUISurf = NULL);
static CBitmap *CreateViaLoadImage(HINSTANCE hInst, LPCTSTR tszName, UINT uType, int cx, int cy, UINT fuLoad);
static CBitmap *CreateFromResource(HINSTANCE hInst, UINT uID) {return CreateFromResource(hInst, MAKEINTRESOURCE(uID));}
static CBitmap *CreateFromResource(HINSTANCE hInst, LPCTSTR tszName);
static CBitmap *CreateFromFile(LPCTSTR tszFileName);
static CBitmap *StealToCreate(HBITMAP &refbm);
static CBitmap *Create(int cx, int cy, HDC hDC = NULL) {SIZE size = {cx, cy}; return Create(size, hDC);}
static CBitmap *Create(SIZE, HDC = NULL);
static CBitmap *Create(SIZE, COLORREF, HDC = NULL);
static CBitmap *CreateHorzGradient(const RECT &, COLORREF, COLORREF);
BOOL GetSize(SIZE *psize);
void AssumeSize(SIZE size);
BOOL FigureSize();
CBitmap *CreateResizedTo(SIZE size, HDC hDC = NULL, int iStretchMode = HALFTONE, BOOL bStretch = TRUE);
CBitmap *Dup();
BOOL Get(HDC hDC, POINT point, SIZE size);
BOOL Get(HDC hDC, POINT point);
BOOL Draw(HDC hDC) {return Draw(hDC, 0, 0);}
BOOL Draw(HDC hDC, SIZE size) {return Draw(hDC, 0, 0, size);}
BOOL Draw(HDC hDC, int x, int y, SIZE size) {POINT t = {x, y}; return Draw(hDC, t, size);}
BOOL Draw(HDC hDC, int x, int y) {POINT t = {x, y}; return Draw(hDC, t);}
BOOL Draw(HDC hDC, POINT origin) {SIZE t = {0, 0}; return Draw(hDC, origin, t, TRUE);}
BOOL Draw(HDC hDC, POINT origin, SIZE size, BOOL bAll = FALSE);
BOOL Blend(HDC hDC) {return Blend(hDC, 0, 0);}
BOOL Blend(HDC hDC, SIZE size) {return Blend(hDC, 0, 0, size);}
BOOL Blend(HDC hDC, int x, int y, SIZE size) {POINT t = {x, y}; return Blend(hDC, t, size);}
BOOL Blend(HDC hDC, int x, int y) {POINT t = {x, y}; return Blend(hDC, t);}
BOOL Blend(HDC hDC, POINT origin) {SIZE t = {0, 0}; return Blend(hDC, origin, t, TRUE);}
BOOL Blend(HDC hDC, POINT origin, SIZE size, BOOL bAll = FALSE);
HDC BeginPaintInto(HDC hCDC = NULL);
void EndPaintInto(HDC &hDC);
BOOL MapToDC(HDC hDCTo, HDC hDCMapFrom = NULL);
private:
HBITMAP m_hbm;
SIZE m_size;
BOOL m_bSizeKnown;
HDC m_hDCInto;
HGDIOBJ m_hOldBitmap;
void PopOut();
void PopIn();
};
#endif //__CBITMAP_H__

View File

@@ -0,0 +1,169 @@
#include "common.hpp"
#include "id3dsurf.h"
class CDirect3DSurface8: public IDirect3DSurface8Clone
{
public:
CDirect3DSurface8();
~CDirect3DSurface8();
/* ULONG AddRef();
HRESULT QueryInterface(REFIID iid, void **ppvObject);
ULONG Release();*/
// IUnknown methods
STDMETHOD(QueryInterface) (REFIID riid,
VOID **ppvObj);
STDMETHOD_(ULONG,AddRef) ();
STDMETHOD_(ULONG,Release) ();
// IBuffer methods
STDMETHOD(SetPrivateData)(REFGUID riid,
CONST VOID *pvData,
DWORD cbData,
DWORD dwFlags);
STDMETHOD(GetPrivateData)(REFGUID riid,
VOID *pvData,
DWORD *pcbData);
STDMETHOD(FreePrivateData)(REFGUID riid);
STDMETHOD(GetContainer)(REFIID riid,
void **ppContainer);
STDMETHOD(GetDevice)(IDirect3DDevice8 **ppDevice);
// IDirect3DSurface8 methods
STDMETHOD_(D3DSURFACE_DESC, GetDesc)();
STDMETHOD(LockRect)(D3DLOCKED_RECT *pLockedRectData,
CONST RECT *pRect,
DWORD dwFlags);
STDMETHOD(UnlockRect)();
BOOL Create(int iWidth, int iHeight);
/* HRESULT GetDevice(IDirect3DDevice8** ppDevice);
HRESULT SetPrivateData(REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags);
HRESULT GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData);
HRESULT FreePrivateData(REFGUID refguid);
HRESULT GetContainer(REFIID riid, void** ppContainer);
D3DSURFACE_DESC GetDesc();
HRESULT LockRect(D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags);
HRESULT UnlockRect();*/
private:
int m_iRefCount;
BYTE *m_pData;
D3DSURFACE_DESC m_Desc;
};
CDirect3DSurface8::CDirect3DSurface8() : m_pData(NULL), m_iRefCount(1)
{
}
CDirect3DSurface8::~CDirect3DSurface8()
{
delete[] m_pData;
}
BOOL CDirect3DSurface8::Create(int iWidth, int iHeight)
{
m_pData = new BYTE[iWidth * iHeight * 4];
if (!m_pData) return FALSE;
m_Desc.Format = D3DFMT_A8R8G8B8;
m_Desc.Type = D3DRTYPE_SURFACE;
m_Desc.Usage = 0;
m_Desc.Pool = D3DPOOL_SYSTEMMEM;
m_Desc.Size = iWidth * iHeight * 4;
m_Desc.MultiSampleType = D3DMULTISAMPLE_NONE;
m_Desc.Width = iWidth;
m_Desc.Height = iHeight;
return TRUE;
}
STDMETHODIMP_(ULONG) CDirect3DSurface8::AddRef()
{
return ++m_iRefCount;
}
STDMETHODIMP CDirect3DSurface8::QueryInterface(REFIID iid, void **ppvObject)
{
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CDirect3DSurface8::Release()
{
if (!--m_iRefCount)
{
delete this;
return 0;
}
return m_iRefCount;
}
/////////// Dummy implementations ///////////////
STDMETHODIMP CDirect3DSurface8::SetPrivateData(REFGUID riid, CONST VOID *pvData, DWORD cbData, DWORD dwFlags)
{
return S_OK;
}
STDMETHODIMP CDirect3DSurface8::GetPrivateData(REFGUID riid, VOID *pvData, DWORD *pcbData)
{
return S_OK;
}
STDMETHODIMP CDirect3DSurface8::FreePrivateData(REFGUID riid)
{
return S_OK;
}
STDMETHODIMP CDirect3DSurface8::GetContainer(REFIID riid, void **ppContainer)
{
return S_OK;
}
STDMETHODIMP CDirect3DSurface8::GetDevice(IDirect3DDevice8 **ppDevice)
{
return S_OK;
}
// Required implementation
STDMETHODIMP_(D3DSURFACE_DESC) CDirect3DSurface8::GetDesc()
{
return m_Desc;
}
// Assume the entire surface is being locked.
STDMETHODIMP CDirect3DSurface8::LockRect(D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags)
{
pLockedRect->Pitch = m_Desc.Width * 4;
pLockedRect->pBits = m_pData;
return S_OK;
}
STDMETHODIMP CDirect3DSurface8::UnlockRect()
{
return S_OK;
}
IDirect3DSurface8 *GetCloneSurface(int iWidth, int iHeight)
{
CDirect3DSurface8 *pSurf = new CDirect3DSurface8;
if (!pSurf) return NULL;
if (!pSurf->Create(iWidth, iHeight))
{
delete pSurf;
return NULL;
}
return (IDirect3DSurface8*)pSurf;
}

View File

@@ -0,0 +1,615 @@
//-----------------------------------------------------------------------------
// File: cdevicecontrol.cpp
//
// Desc: CDeviceControl is a class that encapsulate the functionality of a
// device control (or a callout). CDeviceView accesses it to retrieve/
// save information about the control.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
CDeviceControl::CDeviceControl(CDeviceUI &ui, CDeviceView &view) :
m_ui(ui),
m_view(view),
m_bHighlight(FALSE),
m_ptszCaption(NULL),
m_dwDrawTextFlags(0),
m_FontHeight(-1),
m_bCalledCalcCallout(FALSE),
m_bPlacedOnlyFirstCorner(FALSE),
m_bInit(FALSE),
m_dwCalloutAlign(CAF_TOPLEFT),
m_nLinePoints(0),
m_dwDeviceControlOffset((DWORD)-1),
m_bOffsetAssigned(FALSE),
m_pbmOverlay(NULL),
m_pbmHitMask(NULL),
m_ptszOverlayPath(NULL),
m_bCaptionClipped(FALSE)
{
}
CDeviceControl::~CDeviceControl()
{
DEVICEUINOTIFY uin;
uin.from = DEVUINFROM_CONTROL;
uin.control.pControl = (CDeviceControl *)this;
uin.msg = DEVUINM_ONCONTROLDESTROY;
m_ui.Notify(uin);
if (m_ptszCaption)
free(m_ptszCaption);
delete m_pbmOverlay;
delete m_ptszOverlayPath;
}
void CDeviceControl::SetCaption(LPCTSTR tszCaption, BOOL bFixed)
{
LPTSTR tszNewCaption = NULL;
m_bFixed = bFixed;
if (tszCaption != NULL)
{
tszNewCaption = _tcsdup(tszCaption);
if (tszNewCaption == NULL)
return;
}
free(m_ptszCaption);
m_ptszCaption = tszNewCaption;
tszNewCaption = NULL;
CalcCallout();
Invalidate();
}
LPCTSTR CDeviceControl::GetCaption()
{
return (LPCTSTR)m_ptszCaption;
}
BOOL CDeviceControl::HitControl(POINT point)
{
return FALSE;
}
DEVCTRLHITRESULT CDeviceControl::HitTest(POINT test)
{
if (!m_bInit)
return DCHT_NOHIT;
if (m_ui.InEditMode() &&
PtInRect(&m_rectCalloutMax, test))
return DCHT_MAXRECT;
PrepCallout();
if (PtInRect(&m_rectCallout, test))
return DCHT_CAPTION;
if (HitControl(test))
return DCHT_CONTROL;
return DCHT_NOHIT;
}
void CDeviceControl::Init()
{
m_uin.from = DEVUINFROM_CONTROL;
m_uin.control.pControl = this;
CalcCallout();
m_bInit = TRUE;
}
// We will have to know the view's scrolling offset to adjust the tooltip's position.
void CDeviceControl::OnMouseOver(POINT point)
{
// Tooltip only if the callout text is clipped.
if (m_bCaptionClipped)
{
TOOLTIPINITPARAM ttip;
ttip.hWndParent = GetParent(m_view.m_hWnd); // Parent is the page window.
ttip.iSBWidth = 0;
ttip.dwID = m_dwDeviceControlOffset;
ttip.hWndNotify = m_view.m_hWnd;
ttip.tszCaption = GetCaption();
CFlexToolTip::UpdateToolTipParam(ttip);
} else
CFlexWnd::s_ToolTip.SetToolTipParent(NULL);
m_uin.msg = DEVUINM_MOUSEOVER;
m_ui.Notify(m_uin);
}
void CDeviceControl::OnClick(POINT point, BOOL bLeft, BOOL bDoubleClick)
{
// If this control is not assigned, and we are in view mode, we should not do anything (highlight).
if (!lstrcmp(m_ptszCaption, g_tszUnassignedControlCaption) && !m_ui.m_uig.InEditMode())
return;
m_uin.msg = bDoubleClick ? DEVUINM_DOUBLECLICK : DEVUINM_CLICK;
m_uin.click.bLeftButton = bLeft;
m_ui.Notify(m_uin);
}
void CDeviceControl::Unpopulate()
{
}
void CDeviceControl::Highlight(BOOL bHighlight)
{
if (m_bHighlight == bHighlight)
return;
// If the callout text is the default text, no action is assigned, and we don't highlight it.
if (!lstrcmp(m_ptszCaption, g_tszUnassignedControlCaption) && bHighlight && !m_ui.m_uig.InEditMode())
return;
m_bHighlight = bHighlight;
// If the view has scrolling enabled, we need to adjust the scroll
// bar position to make this callout visible.
if (bHighlight)
m_view.ScrollToMakeControlVisible(m_rectCalloutMax);
CalcCallout();
// We do not invalidate rectangle if we are unhighlighting. Let CDeviceView handle that.
if (bHighlight) Invalidate();
}
void CDeviceControl::GetInfo(GUID &rGuid, DWORD &rdwOffset)
{
m_ui.GetDeviceInstanceGuid(rGuid);
rdwOffset = m_dwDeviceControlOffset;
}
BOOL CDeviceControl::PrepCaption()
{
if (m_ptszCaption != NULL)
return TRUE;
m_ptszCaption = _tcsdup(g_tszUnassignedControlCaption);
return m_ptszCaption != NULL;
}
void CDeviceControl::PrepLinePoints()
{
if (m_nLinePoints > 0)
return;
m_nLinePoints = 1;
POINT pt = {0, 0};
if (m_dwCalloutAlign & CAF_LEFT)
pt.x = m_rectCalloutMax.left;
if (m_dwCalloutAlign & CAF_RIGHT)
pt.x = m_rectCalloutMax.right - 1;
if (m_dwCalloutAlign & CAF_TOP)
pt.y = m_rectCalloutMax.top;
if (m_dwCalloutAlign & CAF_BOTTOM)
pt.y = m_rectCalloutMax.bottom - 1;
if (!(m_dwCalloutAlign & (CAF_LEFT | CAF_RIGHT)))
pt.x = (m_rectCalloutMax.left + m_rectCalloutMax.right - 1) / 2;
if (!(m_dwCalloutAlign & (CAF_BOTTOM | CAF_TOP)))
pt.y = (m_rectCalloutMax.top + m_rectCalloutMax.bottom - 1) / 2;
m_rgptLinePoint[0] = pt;
}
void CDeviceControl::PrepCallout()
{
if (m_bCalledCalcCallout)
return;
CalcCallout();
}
void CDeviceControl::PrepFont()
{
if (m_FontHeight != -1)
return;
HDC hDC = CreateCompatibleDC(NULL);
if (hDC != NULL)
{
RECT rect = {0, 0, 500, 1};
{
CPaintHelper ph(m_ui.m_uig, hDC);
ph.SetFont(UIF_CALLOUT);
m_FontHeight = DrawText(hDC, _T("Testify"), -1, &rect, m_dwDrawTextFlags);
}
DeleteDC(hDC);
}
}
void CDeviceControl::CalcCallout()
{
m_bCalledCalcCallout = TRUE;
RECT max = m_rectCalloutMax;
InflateRect(&max, -1, -1);
RECT rect = max;
rect.bottom = rect.top + 1;
PrepFont();
HDC hDC = CreateCompatibleDC(NULL);
{
CPaintHelper ph(m_ui.m_uig, hDC);
ph.SetFont(UIF_CALLOUT);
// We make sure the max rect height is at least same as the font requires.
m_dwDrawTextFlags = DT_SINGLELINE | DT_CALCRECT | DT_NOPREFIX | DT_END_ELLIPSIS | DT_EDITCONTROL;
RECT hrect = rect;
DrawText(hDC, m_ptszCaption, -1, &hrect, m_dwDrawTextFlags);
if (hrect.bottom > max.bottom) max.bottom = hrect.bottom;
m_dwDrawTextFlags = DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX | DT_END_ELLIPSIS | DT_EDITCONTROL;
// first, drawtext/calcrect into the temporary rect
if (!PrepCaption())
{
return;
}
int th = DrawText(hDC, m_ptszCaption, -1, &rect, m_dwDrawTextFlags);
m_bCaptionClipped = rect.bottom > max.bottom || rect.right > max.right; // Set clipped flag.
BOOL bSingleTextLine = th <= m_FontHeight;
if (rect.right > max.right)
{
bSingleTextLine = TRUE;
rect.right = max.right;
}
if (bSingleTextLine)
m_dwDrawTextFlags &= ~DT_WORDBREAK;
m_dwDrawTextFlags &= ~DT_CALCRECT;
RECT rect2 = rect;
if (rect2.bottom > max.bottom)
rect2.bottom = max.bottom;
th = DrawText(hDC, m_ptszCaption, -1, &rect2, m_dwDrawTextFlags);
int ith = (th / m_FontHeight) * m_FontHeight;
rect.bottom = rect.top + ith + 1;
}
DeleteDC(hDC);
hDC = NULL;
if (rect.bottom > max.bottom)
rect.bottom = max.bottom;
assert(rect.right <= max.right);
assert(rect.bottom <= max.bottom);
PrepLinePoints();
POINT adj = {0, 0};
assert(rect.left == max.left);
assert(rect.top == max.top);
int w = rect.right - rect.left;
int h = rect.bottom - rect.top;
int mw = max.right - max.left;
int mh = max.bottom - max.top;
int dw = mw - w, dh = mh - h;
int cx = mw / 2 + max.left, cy = mh / 2 + max.top;
int cl = cx - w / 2, ct = cy - h / 2;
assert(dw >= 0);
assert(dh >= 0);
if (m_dwCalloutAlign & CAF_RIGHT && rect.right < max.right)
adj.x = max.right - rect.right;
if (m_dwCalloutAlign & CAF_BOTTOM && rect.bottom < max.bottom)
adj.y = max.bottom - rect.bottom;
if (!(m_dwCalloutAlign & (CAF_RIGHT | CAF_LEFT)) && w < mw && rect.left != cl)
adj.x = cl - rect.left;
if (!(m_dwCalloutAlign & (CAF_BOTTOM | CAF_TOP)) && h < mh && rect.top != ct)
adj.y = ct - rect.top;
OffsetRect(&rect, adj.x, adj.y);
InflateRect(&rect, 1, 1);
m_rectCallout = rect;
}
BOOL CDeviceControl::DrawOverlay(HDC hDC)
{
if (m_pbmOverlay == NULL)
return FALSE;
return m_pbmOverlay->Blend(hDC, m_ptOverlay);
}
void CDeviceControl::OnPaint(HDC hDC)
{
if (!m_bInit)
return;
// If we are in view mode and the callout is not assigned, don't draw anything.
if (!m_ui.m_uig.InEditMode() && !lstrcmp(m_ptszCaption, g_tszUnassignedControlCaption))
return;
PrepCallout();
CPaintHelper ph(m_ui.m_uig, hDC);
UIELEMENT eCallout = m_bHighlight ? UIE_CALLOUTHIGH : UIE_CALLOUT;
// draw lines...
if (m_nLinePoints > 1)
{
ph.SetElement(UIE_CALLOUTSHADOW);
PolyLineArrowShadow(hDC, m_rgptLinePoint, m_nLinePoints);
ph.SetElement(eCallout);
PolyLineArrow(hDC, m_rgptLinePoint, m_nLinePoints);
}
// draw text
ph.SetElement(eCallout);
RECT rect = m_rectCallout;
InflateRect(&rect, -1, -1);
// If this control is assigned an action with DIA_FIXED (m_bFixed), use gray color for text.
COLORREF OldColor;
if (m_bFixed)
{
OldColor = ::SetTextColor(hDC, 0); // Set an arbitrary color to find out what we are currently using.
::SetTextColor(hDC, RGB(GetRValue(OldColor) >> 1, GetGValue(OldColor) >> 1, GetBValue(OldColor) >> 1));
}
if (m_ptszCaption)
DrawText(hDC, m_ptszCaption, -1, &rect, m_dwDrawTextFlags);
if (m_bFixed)
::SetTextColor(hDC, OldColor);
}
void CDeviceControl::Invalidate()
{
m_view.Invalidate();
}
void MakeRect(RECT &rect, POINT a, POINT b)
{
rect.left = min(a.x, b.x);
rect.right = max(a.x, b.x);
rect.top = min(a.y, b.y);
rect.bottom = max(a.y, b.y);
}
void CDeviceControl::PlaceCalloutMaxCorner(int nCorner, POINT point)
{
switch (nCorner)
{
case 0:
m_ptFirstCorner = point;
m_bPlacedOnlyFirstCorner = TRUE;
Invalidate();
break;
case 1:
MakeRect(m_rectCalloutMax, m_ptFirstCorner, point);
m_bPlacedOnlyFirstCorner = FALSE;
if (!m_bInit)
Init();
else
CalcCallout();
Invalidate();
break;
default:
assert(0);
break;
}
}
void CDeviceControl::SetLastLinePoint(int nPoint, POINT point, BOOL bShiftDown)
{
if (!(nPoint >= 0 && nPoint < MAX_DEVICECONTROL_LINEPOINTS))
return;
// Check for SHIFT key state
if (nPoint && bShiftDown) // SHIFT key only makes a difference if we are setting 2nd and subsequent points.
{
// SHIFT key down. Need to draw controlled line.
if (labs(m_rgptLinePoint[nPoint-1].x - point.x) > labs(m_rgptLinePoint[nPoint-1].y - point.y))
{
// Wider. Draw horizontal.
m_rgptLinePoint[nPoint].x = point.x;
m_rgptLinePoint[nPoint].y = m_rgptLinePoint[nPoint-1].y;
} else
{
// Taller. Draw vertical
m_rgptLinePoint[nPoint].x = m_rgptLinePoint[nPoint-1].x;
m_rgptLinePoint[nPoint].y = point.y;
}
} else
m_rgptLinePoint[nPoint] = point; // SHIFT key not down. Draw line as usual.
m_nLinePoints = nPoint + 1;
Invalidate();
if (m_nLinePoints < 2)
return;
POINT prev = m_rgptLinePoint[m_nLinePoints - 2];
// remove identical points
if (point.x == prev.x && point.y == prev.y)
{
m_nLinePoints--;
return;
}
}
void PlaceRectCenter(RECT &rect, POINT point)
{
POINT center = {
(rect.left + rect.right) / 2,
(rect.top + rect.bottom) / 2};
OffsetRect(&rect, point.x - center.x, point.y - center.y);
}
void OffsetRectToWithin(RECT &rect, const RECT &bounds)
{
POINT adj = {0, 0};
if (rect.left < bounds.left)
adj.x = bounds.left - rect.left;
if (rect.right > bounds.right)
adj.x = bounds.right - rect.right;
if (rect.top < bounds.top)
adj.y = bounds.top - rect.top;
if (rect.bottom > bounds.bottom)
adj.y = bounds.bottom - rect.bottom;
OffsetRect(&rect, adj.x, adj.y);
}
void CDeviceControl::Position(POINT point)
{
PlaceRectCenter(m_rectCalloutMax, point);
RECT client;
m_view.GetClientRect(&client);
OffsetRectToWithin(m_rectCalloutMax, client);
CalcCallout();
Invalidate();
}
void CDeviceControl::ConsiderAlignment(POINT point)
{
POINT center = {
(m_rectCalloutMax.right + m_rectCalloutMax.left) / 2,
(m_rectCalloutMax.bottom + m_rectCalloutMax.top) / 2};
SIZE dim = {
m_rectCalloutMax.right - m_rectCalloutMax.left,
m_rectCalloutMax.bottom - m_rectCalloutMax.top};
SIZE delta = {point.x - center.x, point.y - center.y};
int MININ = m_FontHeight;
SIZE in = {max(dim.cx / 4, MININ), max(dim.cy / 4, MININ)};
DWORD align = 0;
if (delta.cx < -in.cx)
align |= CAF_LEFT;
if (delta.cx > in.cx)
align |= CAF_RIGHT;
if (delta.cy < -in.cy)
align |= CAF_TOP;
if (delta.cy > in.cy)
align |= CAF_BOTTOM;
m_dwCalloutAlign = align;
CalcCallout();
Invalidate();
}
DWORD CDeviceControl::GetOffset()
{
if (m_bOffsetAssigned)
return m_dwDeviceControlOffset;
return (DWORD)-1;
}
BOOL CDeviceControl::IsOffsetAssigned()
{
return m_bOffsetAssigned;
}
void CDeviceControl::FillImageInfo(DIDEVICEIMAGEINFOW *pImgInfo)
{
if (!pImgInfo) return;
if (m_ptszOverlayPath != NULL)
CopyStr(pImgInfo->tszImagePath, m_ptszOverlayPath, MAX_PATH);
else
wcscpy(pImgInfo->tszImagePath, L""); // Overlay Image not yet supported
SIZE size = {0, 0};
if (m_pbmOverlay != NULL)
m_pbmOverlay->GetSize(&size);
RECT rect = {m_ptOverlay.x, m_ptOverlay.y,
m_ptOverlay.x + size.cx, m_ptOverlay.y + size.cy};
pImgInfo->dwFlags = DIDIFT_OVERLAY; // This is an overlay
pImgInfo->rcOverlay = rect;
pImgInfo->dwObjID = GetOffset();
pImgInfo->dwcValidPts = m_nLinePoints;
DWORD dwPtsToCopy = m_nLinePoints > 5 ? 5 : m_nLinePoints;
for (DWORD i = 0; i < dwPtsToCopy; ++i)
pImgInfo->rgptCalloutLine[i] = m_rgptLinePoint[i];
pImgInfo->rcCalloutRect = m_rectCalloutMax;
pImgInfo->dwTextAlign = m_dwCalloutAlign;
}
BOOL CDeviceControl::IsMapped()
{
return m_ui.IsControlMapped(this);
}
int CDeviceControl::GetControlIndex()
{
for (int i = 0; i < m_view.GetNumControls(); i++)
if (m_view.GetControl(i) == this)
return i;
return -1;
}
void CDeviceControl::SetLinePoints(int n, POINT *rgpt)
{
assert(n >= 0 && n <= MAX_DEVICECONTROL_LINEPOINTS && rgpt);
if (n < 0)
n = 0;
if (n > MAX_DEVICECONTROL_LINEPOINTS)
n = MAX_DEVICECONTROL_LINEPOINTS;
if (!rgpt)
n = 0;
m_nLinePoints = n;
for (int i = 0; i < n; i++)
m_rgptLinePoint[i] = rgpt[i];
}
void CDeviceControl::SetOverlayPath(LPCTSTR tszPath)
{
if (m_ptszOverlayPath)
free(m_ptszOverlayPath);
m_ptszOverlayPath = NULL;
if (tszPath)
m_ptszOverlayPath = _tcsdup(tszPath);
delete m_pbmOverlay;
m_pbmOverlay = NULL;
if (m_ptszOverlayPath)
{
LPDIRECT3DSURFACE8 pSurf = m_ui.m_uig.GetSurface3D(); // GetSurface3D() calls AddRef() on the surface.
m_pbmOverlay = CBitmap::CreateViaD3DX(m_ptszOverlayPath, pSurf);
if (pSurf)
{
// Release surface instance after we are done with it so we don't leak memory.
pSurf->Release();
pSurf = NULL;
}
}
}
void CDeviceControl::SetOverlayRect(const RECT &r)
{
m_ptOverlay.x = r.left;
m_ptOverlay.y = r.top;
}

View File

@@ -0,0 +1,178 @@
//-----------------------------------------------------------------------------
// File: cdevicecontrol.h
//
// Desc: CDeviceControl is a class that encapsulate the functionality of a
// device control (or a callout). CDeviceView accesses it to retrieve/
// save information about the control.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifdef FORWARD_DECLS
struct DEVICECONTROLSTRUCT;
enum DEVCTRLHITRESULT;
class CDeviceControl;
#else // FORWARD_DECLS
#ifndef __CDEVICECONTROL_H__
#define __CDEVICECONTROL_H__
const int MAX_DEVICECONTROL_LINEPOINTS = 5;
#define CAF_LEFT 1
#define CAF_RIGHT 2
#define CAF_TOP 4
#define CAF_BOTTOM 8
#define CAF_TOPLEFT (CAF_TOP | CAF_LEFT)
#define CAF_TOPRIGHT (CAF_TOP | CAF_RIGHT)
#define CAF_BOTTOMLEFT (CAF_BOTTOM | CAF_LEFT)
#define CAF_BOTTOMRIGHT (CAF_BOTTOM | CAF_RIGHT)
struct DEVICECONTROLSTRUCT {
DEVICECONTROLSTRUCT() : nLinePoints(0) {CopyStr(wszOverlayPath, "", MAX_PATH); SRECT r; rectOverlay = r.r;}
DWORD dwDeviceControlOffset;
int nLinePoints;
POINT rgptLinePoint[MAX_DEVICECONTROL_LINEPOINTS];
DWORD dwCalloutAlign;
RECT rectCalloutMax;
WCHAR wszOverlayPath[MAX_PATH];
RECT rectOverlay;
};
enum DEVCTRLHITRESULT {
DCHT_LINE,
DCHT_CAPTION,
DCHT_MAXRECT,
DCHT_CONTROL,
DCHT_NOHIT
};
class CDeviceControl
{
private:
friend class CDeviceView; // CDeviceView has exclusive right to create/destroy views
CDeviceControl(CDeviceUI &ui, CDeviceView &view);
~CDeviceControl();
CDeviceView &m_view;
CDeviceUI &m_ui;
public:
// Info
int GetViewIndex() { return m_view.GetViewIndex(); }
int GetControlIndex();
// state information
void SetCaption(LPCTSTR tszCaption, BOOL bFixed = FALSE);
LPCTSTR GetCaption();
BOOL IsFixed() { return m_bFixed; }
void Unhighlight() {Highlight(FALSE);}
void Highlight(BOOL bHighlight = TRUE);
BOOL IsHighlighted() {return m_bHighlight;}
void GetInfo(GUID &rGuid, DWORD &rdwOffset);
DWORD GetOffset();
BOOL IsOffsetAssigned();
BOOL HasAction() { return lstrcmp(m_ptszCaption, g_tszUnassignedControlCaption); }
void FillImageInfo(DIDEVICEIMAGEINFOW *pImgInfo); // This fills the structure info about this control
BOOL IsMapped();
int GetMinX() {return m_rectCallout.left;}
int GetMaxX() {return m_rectCallout.right;}
int GetMinY() {return m_rectCallout.top;}
int GetMaxY() {return m_rectCallout.bottom;}
const RECT &GetCalloutMaxRect() const { return m_rectCalloutMax; }
// hit testing (in coord's relative to view's origin)
DEVCTRLHITRESULT HitTest(POINT test);
// simple notification
void OnMouseOver(POINT point);
void OnClick(POINT point, BOOL bLeft, BOOL bDoubleClick = FALSE);
void OnPaint(HDC hDC);
// redrawing
void Invalidate();
// editing
void PlaceCalloutMaxCorner(int nCorner, POINT point);
void ConsiderAlignment(POINT point);
void FinalizeAlignment() { }
void SetLastLinePoint(int nPoint, POINT point, BOOL bShiftDown);
void Position(POINT point);
BOOL ReachedMaxLinePoints() { return m_nLinePoints >= MAX_DEVICECONTROL_LINEPOINTS; }
int GetNextLinePointIndex() { return m_nLinePoints; }
BOOL HasOverlay() { return m_pbmOverlay != NULL; }
// population
void SetObjID(DWORD dwObjID) { m_dwDeviceControlOffset = dwObjID; m_bOffsetAssigned = TRUE; }
void SetLinePoints(int n, POINT *rgpt);
void SetCalloutMaxRect(const RECT &r) { m_rectCalloutMax = r; CalcCallout(); }
void SetAlignment(DWORD a) { m_dwCalloutAlign = a; }
void SetOverlayPath(LPCTSTR tszPath);
void SetOverlayRect(const RECT &r);
void Init();
private:
// editing vars/helpers
POINT m_ptFirstCorner;
BOOL m_bPlacedOnlyFirstCorner;
// helpers
void Unpopulate();
BOOL m_bInit;
BOOL m_bFixed; // Whether this control is assigned an action with DIA_APPFIXED flag.
DEVICEUINOTIFY m_uin;
BOOL HitControl(POINT point);
BOOL DrawOverlay(HDC hDC);
// device information
DWORD m_dwDeviceControlOffset;
BOOL m_bOffsetAssigned;
// location/indication/visualization...
// (all relative to view's origin)
// overlay
LPTSTR m_ptszOverlayPath;
CBitmap *m_pbmOverlay;
CBitmap *m_pbmHitMask;
POINT m_ptOverlay;
POINT m_ptHitMask;
// caption (allocated and stored here)
LPTSTR m_ptszCaption;
BOOL m_bCaptionClipped; // Whether the caption is clipped when drawn by DrawTextEx.
// coloring
BOOL m_bHighlight;
// line points... first connects to callout, last points to control
int m_nLinePoints;
POINT m_rgptLinePoint[MAX_DEVICECONTROL_LINEPOINTS];
// callout specs
DWORD m_dwCalloutAlign; // where the line emerges from the callout
RECT m_rectCallout, m_rectCalloutMax; // current callout rect, and max rect
// gdi
DWORD m_dwDrawTextFlags;
int m_FontHeight;
void PrepFont();
BOOL PrepCaption();
void PrepLinePoints();
void CalcCallout();
void PrepCallout();
BOOL m_bCalledCalcCallout;
};
#endif //__CDEVICECONTROL_H__
#endif // FORWARD_DECLS

View File

@@ -0,0 +1,389 @@
/******************************************************************************
* File: CDeviceUI.cpp
*
* Desc:
*
* CDeviceUI is a helper that holds all the views and a bunch of
* information for a specific device. It has a CFlexWnd whose
* handler it sets to the CDeviceView for the current view,
* thus reusing one window to implement multiple pages.
*
* All CDeviceViews and CDeviceControls have a reference to the CDeviceUI
* that created them (m_ui). Thus, they also have access to the
* CUIGlobals, since CDeviceUI has a reference to them (m_ui.m_uig).
* CDeviceUI also provides the following read-only public variables
* for convenience, all referring to the device this CDeviceUI
* represents:
*
* const DIDEVICEINSTANCEW &m_didi;
* const LPDIRECTINPUTDEVICE8W &m_lpDID;
* const DIDEVOBJSTRUCT &m_os;
*
* See usefuldi.h for a description of DIDEVOBJSTRUCT.
*
* CDeviceUI communicates to the rest of the UI via the CDeviceUINotify
* abstract base class. Another class (in our case CDIDeviceActionConfigPage)
* must derive from CDeviceUINotify, and define the DeviceUINotify() and
* IsControlMapped() virtual functions. This derived class must be passed as
* the last parameter to CDeviceUI's Init() function. All the views and
* controls within the views notify the UI of user actions via m_ui.Notify(),
* so that all actionformat manipulation can be done in the page class. The
* views and controls themselves never touch the actionformat. See the
* DEVICEUINOTIFY structure below for information on the parameter passed
* through Notify()/DeviceUINotify().
*
* Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
*
***************************************************************************/
#include "common.hpp"
#include <dinputd.h>
#include "configwnd.h"
#define DIPROP_MAPFILE MAKEDIPROP(0xFFFD)
CDeviceUI::CDeviceUI(CUIGlobals &uig, IDIConfigUIFrameWindow &uif) :
m_uig(uig), m_UIFrame(uif),
m_didi(m_priv_didi), m_lpDID(m_priv_lpDID), m_os(m_priv_os),
m_pCurView(NULL),
m_pNotify(NULL), m_hWnd(NULL), m_bInEditMode(FALSE)
{
m_priv_lpDID = NULL;
}
CDeviceUI::~CDeviceUI()
{
Unpopulate();
}
HRESULT CDeviceUI::Init(const DIDEVICEINSTANCEW &didi, LPDIRECTINPUTDEVICE8W lpDID, HWND hWnd, CDeviceUINotify *pNotify)
{tracescope(__ts, _T("CDeviceUI::Init()...\n"));
// save the params
m_priv_didi = didi;
m_priv_lpDID = lpDID;
m_pNotify = pNotify;
m_hWnd = hWnd;
// fail if we don't have lpDID
if (m_lpDID == NULL)
{
etrace(_T("CDeviceUI::Init() was passed a NULL lpDID!\n"));
return E_FAIL;
}
// fill the devobjstruct
HRESULT hr = FillDIDeviceObjectStruct(m_priv_os, lpDID);
if (FAILED(hr))
{
etrace1(_T("FillDIDeviceObjectStruct() failed, returning 0x%08x\n"), hr);
return hr;
}
// view rect needs to be set before populating so the views are
// created with the correct dimensions
m_ViewRect = g_ViewRect;
// populate
hr = PopulateAppropriately(*this);
if (FAILED(hr))
return hr;
// if there are no views, return
if (GetNumViews() < 1)
{
Unpopulate();
return E_FAIL;
}
// show the first view
SetView(0);
return hr;
}
void CDeviceUI::Unpopulate()
{
m_pCurView = NULL;
for (int i = 0; i < GetNumViews(); i++)
{
if (m_arpView[i] != NULL)
delete m_arpView[i];
m_arpView[i] = NULL;
}
m_arpView.RemoveAll();
Invalidate();
}
void CDeviceUI::SetView(int nView)
{
if (nView >= 0 && nView < GetNumViews())
SetView(m_arpView[nView]);
}
void CDeviceUI::SetView(CDeviceView *pView)
{
if (m_pCurView != NULL)
ShowWindow(m_pCurView->m_hWnd, SW_HIDE);
m_pCurView = pView;
if (m_pCurView != NULL)
ShowWindow(m_pCurView->m_hWnd, SW_SHOW);
}
CDeviceView *CDeviceUI::GetView(int nView)
{
if (nView >= 0 && nView < GetNumViews())
return m_arpView[nView];
else
return NULL;
}
CDeviceView *CDeviceUI::GetCurView()
{
return m_pCurView;
}
int CDeviceUI::GetViewIndex(CDeviceView *pView)
{
if (GetNumViews() == 0)
return -1;
for (int i = 0; i < GetNumViews(); i++)
if (m_arpView[i] == pView)
return i;
return -1;
}
int CDeviceUI::GetCurViewIndex()
{
return GetViewIndex(m_pCurView);
}
// gets the thumbnail for the specified view,
// using the selected version if the view is selected
CBitmap *CDeviceUI::GetViewThumbnail(int nView)
{
return GetViewThumbnail(nView, GetView(nView) == GetCurView());
}
// gets the thumbnail for the specified view,
// specifiying whether or not we want the selected version
CBitmap *CDeviceUI::GetViewThumbnail(int nView, BOOL bSelected)
{
CDeviceView *pView = GetView(nView);
if (pView == NULL)
return NULL;
return pView->GetImage(bSelected ? DVI_SELTHUMB : DVI_THUMB);
}
void CDeviceUI::DoForAllControls(DEVCTRLCALLBACK callback, LPVOID pVoid, BOOL bFixed)
{
int nv = GetNumViews();
for (int v = 0; v < nv; v++)
{
CDeviceView *pView = GetView(v);
if (pView == NULL)
continue;
int nc = pView->GetNumControls();
for (int c = 0; c < nc; c++)
{
CDeviceControl *pControl = pView->GetControl(c);
if (pControl == NULL)
continue;
callback(pControl, pVoid, bFixed);
}
}
}
typedef struct _DFCIAO {
DWORD dwOffset;
DEVCTRLCALLBACK callback;
LPVOID pVoid;
} DFCIAO;
void DoForControlIfAtOffset(CDeviceControl *pControl, LPVOID pVoid, BOOL bFixed)
{
DFCIAO &dfciao = *((DFCIAO *)pVoid);
if (pControl->GetOffset() == dfciao.dwOffset)
dfciao.callback(pControl, dfciao.pVoid, bFixed);
}
void CDeviceUI::DoForAllControlsAtOffset(DWORD dwOffset, DEVCTRLCALLBACK callback, LPVOID pVoid, BOOL bFixed)
{
DFCIAO dfciao;
dfciao.dwOffset = dwOffset;
dfciao.callback = callback;
dfciao.pVoid = pVoid;
DoForAllControls(DoForControlIfAtOffset, &dfciao, bFixed);
}
void SetControlCaptionTo(CDeviceControl *pControl, LPVOID pVoid, BOOL bFixed)
{
pControl->SetCaption((LPCTSTR)pVoid, bFixed);
}
void CDeviceUI::SetAllControlCaptionsTo(LPCTSTR tszCaption)
{
DoForAllControls(SetControlCaptionTo, (LPVOID)tszCaption);
}
void CDeviceUI::SetCaptionForControlsAtOffset(DWORD dwOffset, LPCTSTR tszCaption, BOOL bFixed)
{
DoForAllControlsAtOffset(dwOffset, SetControlCaptionTo, (LPVOID)tszCaption, bFixed);
}
void CDeviceUI::Invalidate()
{
if (m_pCurView != NULL)
m_pCurView->Invalidate();
}
void CDeviceUI::SetEditMode(BOOL bEdit)
{
if (bEdit == m_bInEditMode)
return;
m_bInEditMode = bEdit;
Invalidate();
}
void CDeviceUI::SetDevice(LPDIRECTINPUTDEVICE8W lpDID)
{
m_priv_lpDID = lpDID;
}
BOOL CDeviceUI::IsControlMapped(CDeviceControl *pControl)
{
if (pControl == NULL || m_pNotify == NULL)
return FALSE;
return m_pNotify->IsControlMapped(pControl);
}
void CDeviceUI::Remove(CDeviceView *pView)
{
if (pView == NULL)
return;
int i = GetViewIndex(pView);
if (i < 0 || i >= GetNumViews())
{
assert(0);
return;
}
if (pView == m_pCurView)
m_pCurView = NULL;
if (m_arpView[i] != NULL)
{
m_arpView[i]->RemoveAll();
delete m_arpView[i];
}
m_arpView[i] = NULL;
m_arpView.RemoveAt(i);
if (m_arpView.GetSize() < 1)
RequireAtLeastOneView();
else if (m_pCurView == NULL)
{
SetView(0);
NumViewsChanged();
}
}
void CDeviceUI::RemoveAll()
{
m_pCurView = NULL;
for (int i = 0; i < GetNumViews(); i++)
{
if (m_arpView[i] != NULL)
delete m_arpView[i];
m_arpView[i] = NULL;
}
m_arpView.RemoveAll();
RequireAtLeastOneView();
}
CDeviceView *CDeviceUI::NewView()
{
// allocate new view, continuing on if it fails
CDeviceView *pView = new CDeviceView(*this);
if (pView == NULL)
return NULL;
// add view to array
m_arpView.SetAtGrow(m_arpView.GetSize(), pView);
// create view
pView->Create(m_hWnd, m_ViewRect, FALSE);
// let the page update to indicate viewness
NumViewsChanged();
return pView;
}
CDeviceView *CDeviceUI::UserNewView()
{
CDeviceView *pView = NewView();
if (!pView)
return NULL;
pView->AddWrappedLineOfText(
(HFONT)m_uig.GetFont(UIE_PICCUSTOMTEXT),
m_uig.GetTextColor(UIE_PICCUSTOMTEXT),
m_uig.GetBkColor(UIE_PICCUSTOMTEXT),
_T("Customize This View"));
pView->MakeMissingImages();
Invalidate();
return pView;
}
void CDeviceUI::RequireAtLeastOneView()
{
if (GetNumViews() > 0)
return;
CDeviceView *pView = NewView();
if (!pView)
return;
pView->AddWrappedLineOfText(
(HFONT)m_uig.GetFont(UIE_PICCUSTOMTEXT),
m_uig.GetTextColor(UIE_PICCUSTOMTEXT),
m_uig.GetBkColor(UIE_PICCUSTOMTEXT),
_T("Customize This View"));
pView->AddWrappedLineOfText(
(HFONT)m_uig.GetFont(UIE_PICCUSTOM2TEXT),
m_uig.GetTextColor(UIE_PICCUSTOM2TEXT),
m_uig.GetBkColor(UIE_PICCUSTOM2TEXT),
_T("The UI requires at least one view per device"));
pView->MakeMissingImages();
SetView(pView);
}
void CDeviceUI::NumViewsChanged()
{
DEVICEUINOTIFY uin;
uin.msg = DEVUINM_NUMVIEWSCHANGED;
Notify(uin);
}

View File

@@ -0,0 +1,232 @@
/******************************************************************************
* File: CDeviceUI.h
*
* Desc:
*
* CDeviceUI is a helper that holds all the views and a bunch of
* information for a specific device. It has a CFlexWnd whose
* handler it sets to the CDeviceView for the current view,
* thus reusing one window to implement multiple pages.
*
* All CDeviceViews and CDeviceControls have a reference to the CDeviceUI
* that created them (m_ui). Thus, they also have access to the
* CUIGlobals, since CDeviceUI has a reference to them (m_ui.m_uig).
* CDeviceUI also provides the following read-only public variables
* for convenience, all referring to the device this CDeviceUI
* represents:
*
* const DIDEVICEINSTANCEW &m_didi;
* const LPDIRECTINPUTDEVICE8W &m_lpDID;
* const DIDEVOBJSTRUCT &m_os;
*
* See usefuldi.h for a description of DIDEVOBJSTRUCT.
*
* CDeviceUI communicates to the rest of the UI via the CDeviceUINotify
* abstract base class. Another class (in our case CDIDeviceActionConfigPage)
* must derive from CDeviceUINotify, and define the DeviceUINotify() and
* IsControlMapped() virtual functions. This derived class must be passed as
* the last parameter to CDeviceUI's Init() function. All the views and
* controls within the views notify the UI of user actions via m_ui.Notify(),
* so that all actionformat manipulation can be done in the page class. The
* views and controls themselves never touch the actionformat. See the
* DEVICEUINOTIFY structure below for information on the parameter passed
* through Notify()/DeviceUINotify().
*
* Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
*
***************************************************************************/
#ifdef FORWARD_DECLS
struct DEVICEUINOTIFY;
struct UIDELETENOTE;
class CDeviceUINotify;
class CDeviceUI;
#else // FORWARD_DECLS
#ifndef __CDEVICEUI_H__
#define __CDEVICEUI_H__
enum {
DEVUINM_NUMVIEWSCHANGED,
DEVUINM_ONCONTROLDESTROY,
DEVUINM_MOUSEOVER,
DEVUINM_CLICK,
DEVUINM_DOUBLECLICK,
DEVUINM_SELVIEW,
DEVUINM_INVALID,
DEVUINM_UNASSIGNCALLOUT,
DEVUINM_RENEWDEVICE
};
enum {
DEVUINFROM_CONTROL,
DEVUINFROM_THUMBNAIL,
DEVUINFROM_SELWND,
DEVUINFROM_VIEWWND,
DEVUINFROM_INVALID
};
struct DEVICEUINOTIFY {
DEVICEUINOTIFY() : msg(DEVUINM_INVALID), from(DEVUINFROM_INVALID) {}
int msg;
int from;
union {
struct {
CDeviceControl *pControl;
} control;
struct {
CDeviceView *pView;
BOOL bSelected;
} thumbnail;
struct {
int dummy;
} selwnd;
struct {
int dummy;
} viewwnd;
};
union {
struct {
int nView;
} selview;
struct {
POINT point;
} mouseover;
struct {
BOOL bLeftButton;
} click;
};
};
enum UIDELETENOTETYPE {
UIDNT_VIEW,
UIDNT_CONTROL,
};
struct UIDELETENOTE {
UIDELETENOTETYPE eType;
int nViewIndex;
int nControlIndex;
DWORD dwObjID;
};
typedef void (*DEVCTRLCALLBACK)(CDeviceControl *, LPVOID, BOOL);
class CDeviceUINotify
{
public:
virtual void DeviceUINotify(const DEVICEUINOTIFY &) = 0;
virtual BOOL IsControlMapped(CDeviceControl *) = 0;
};
class CDeviceUI
{
public:
CDeviceUI(CUIGlobals &uig, IDIConfigUIFrameWindow &uif);
~CDeviceUI();
// intialization
HRESULT Init(const DIDEVICEINSTANCEW &didi, LPDIRECTINPUTDEVICE8W lpDID, HWND hWnd, CDeviceUINotify *pNotify);
// view state
void SetView(int nView);
void SetView(CDeviceView *pView);
CDeviceView *GetView(int nView);
CDeviceView *GetCurView();
int GetViewIndex(CDeviceView *pView);
int GetCurViewIndex();
int GetNumViews() {return m_arpView.GetSize();}
void NextView() {SetView((GetCurViewIndex() + 1) % GetNumViews());}
void PrevView() {SetView((GetCurViewIndex() - 1 + GetNumViews()) % GetNumViews());}
// gets the thumbnail for the specified view,
// using the selected version if the view is selected
CBitmap *GetViewThumbnail(int nView);
// gets the thumbnail for the specified view,
// specifiying whether or not we want the selected version
CBitmap *GetViewThumbnail(int nView, BOOL bSelected);
// for view/control to notify
void Notify(const DEVICEUINOTIFY &uin)
{if (m_pNotify != NULL) m_pNotify->DeviceUINotify(uin);}
// device control access
void SetAllControlCaptionsTo(LPCTSTR tszCaption);
void SetCaptionForControlsAtOffset(DWORD dwOffset, LPCTSTR tszCaption, BOOL bFixed = FALSE);
void DoForAllControls(DEVCTRLCALLBACK callback, LPVOID pVoid, BOOL bFixed = FALSE);
void DoForAllControlsAtOffset(DWORD dwOffset, DEVCTRLCALLBACK callback, LPVOID pVoid, BOOL bFixed = FALSE);
// page querying
BOOL IsControlMapped(CDeviceControl *);
// other
void GetDeviceInstanceGuid(GUID &rGuid) {rGuid = m_didi.guidInstance;}
// editing
void SetEditMode(BOOL bEdit = TRUE);
BOOL InEditMode() {return m_bInEditMode;}
void Remove(CDeviceView *pView);
void RemoveAll();
#define NVT_USER 1
#define NVT_POPULATE 2
#define NVT_REQUIREATLEASTONE 3
CDeviceView *NewView();
CDeviceView *UserNewView();
void RequireAtLeastOneView();
void SetDevice(LPDIRECTINPUTDEVICE8W lpDID); // Sets the device object that we are using
// drawing
void Invalidate();
// clearing
void Unpopulate();
private:
// delete notes
CArray<UIDELETENOTE, UIDELETENOTE &> m_DeleteNotes;
// who we're going to notify
CDeviceUINotify *m_pNotify;
HWND m_hWnd;
// view state
CArray<CDeviceView *, CDeviceView *&> m_arpView;
CDeviceView *m_pCurView;
BOOL m_bInEditMode;
RECT m_ViewRect;
void NumViewsChanged();
// device globals...
public:
// full access to ui globals and frame
CUIGlobals &m_uig;
IDIConfigUIFrameWindow &m_UIFrame;
// read only public access versions
const DIDEVICEINSTANCEW &m_didi;
const LPDIRECTINPUTDEVICE8W &m_lpDID;
const DIDEVOBJSTRUCT &m_os;
private:
// private versions
DIDEVICEINSTANCEW m_priv_didi;
LPDIRECTINPUTDEVICE8W m_priv_lpDID;
DIDEVOBJSTRUCT m_priv_os;
};
#endif //__CDEVICEUI_H__
#endif // FORWARD_DECLS

View File

@@ -0,0 +1,856 @@
//-----------------------------------------------------------------------------
// File: cdeviceview.cpp
//
// Desc: CDeviceView is a window class derived from CFlexWnd. It represents
// the device view window in which the device and callouts are drawn.
// Each CDeviceView only represents one view. A device that has more
// than one view should have a corresponding number of CDeviceView for it.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
CDeviceView::CDeviceView(CDeviceUI &ui) :
m_ui(ui),
m_pbmImage(NULL),
m_pbmThumb(NULL),
m_pbmSelThumb(NULL),
m_SuperState(0),
m_State(0),
m_SubState(0),
m_OldSuperState(0),
m_OldState(0),
m_OldSubState(0),
m_pControlContext(NULL),
m_ptszImagePath(NULL),
m_bScrollEnable(FALSE),
m_nScrollOffset(0),
m_nViewHeight(g_sizeImage.cy),
m_bForcePaint(FALSE)
{
m_ptNextWLOText.x = m_ptNextWLOText.y = 0;
}
CDeviceView::~CDeviceView()
{
Unpopulate();
}
CDeviceControl *CDeviceView::NewControl()
{
CDeviceControl *pControl = new CDeviceControl(m_ui, *this);
if (!pControl)
return NULL;
m_arpControl.SetAtGrow(m_arpControl.GetSize(), pControl);
return pControl;
}
void CDeviceView::Remove(CDeviceControl *pControl)
{
if (pControl == NULL)
return;
int i = pControl->GetControlIndex();
if (i < 0 || i >= GetNumControls())
{
assert(0);
return;
}
if (pControl == m_pControlContext)
m_pControlContext = NULL;
if (m_arpControl[i] != NULL)
delete m_arpControl[i];
m_arpControl[i] = NULL;
m_arpControl.RemoveAt(i);
Invalidate();
}
void CDeviceView::RemoveAll(BOOL bUser)
{
m_pControlContext = NULL;
for (int i = 0; i < GetNumControls(); i++)
{
if (m_arpControl[i] != NULL)
delete m_arpControl[i];
m_arpControl[i] = NULL;
}
m_arpControl.RemoveAll();
Invalidate();
}
void CDeviceView::Unpopulate(BOOL bInternalOnly)
{
DisableScrollBar();
m_bScrollEnable = FALSE;
if (m_pbmImage != NULL)
delete m_pbmImage;
if (m_pbmThumb != NULL)
delete m_pbmThumb;
if (m_pbmSelThumb != NULL)
delete m_pbmSelThumb;
m_pbmImage = NULL;
m_pbmThumb = NULL;
m_pbmSelThumb = NULL;
free(m_ptszImagePath);
m_ptszImagePath = NULL;
if (!bInternalOnly)
RemoveAll(FALSE);
for (int i = 0; i < m_arpText.GetSize(); i++)
{
if (m_arpText[i])
delete m_arpText[i];
m_arpText[i] = NULL;
}
m_arpText.RemoveAll();
}
void AssureSize(CBitmap *&pbm, SIZE to)
{
if (!pbm)
return;
SIZE from;
if (!pbm->GetSize(&from))
return;
if (from.cx >= to.cx && from.cy >= to.cy)
return;
CBitmap *nbm = CBitmap::Create(to, RGB(0,0,0));
if (!nbm)
return;
HDC hDC = nbm->BeginPaintInto();
pbm->Draw(hDC);
nbm->EndPaintInto(hDC);
delete pbm;
pbm = nbm;
nbm = NULL;
}
CBitmap *CDeviceView::GrabViewImage()
{
CBitmap *pbm = CBitmap::Create(GetClientSize(), RGB(0, 0, 0), NULL);
if (!pbm)
return NULL;
HDC hDC = pbm->BeginPaintInto();
if (!hDC)
{
delete pbm;
return NULL;
}
OnPaint(hDC);
pbm->EndPaintInto(hDC);
return pbm;
}
void CDeviceView::MakeMissingImages()
{
// if (m_pbmImage)
// AssureSize(m_pbmImage, g_sizeImage);
if (m_pbmThumb == NULL)
{
if (m_pbmImage)
m_pbmThumb = m_pbmImage->CreateResizedTo(g_sizeThumb);
else
{
CBitmap *pbmImage = GrabViewImage();
if (pbmImage)
{
AssureSize(pbmImage, g_sizeImage);
m_pbmThumb = pbmImage->CreateResizedTo(g_sizeThumb);
}
delete pbmImage;
}
}
if (m_pbmThumb == NULL)
return;
if (m_pbmSelThumb == NULL)
{
m_pbmSelThumb = m_pbmThumb->Dup();
if (m_pbmSelThumb != NULL)
{
HDC hDC = m_pbmSelThumb->BeginPaintInto();
{
CPaintHelper ph(m_ui.m_uig, hDC);
ph.SetPen(UIP_SELTHUMB);
ph.Rectangle(0, 0, g_sizeThumb.cx, g_sizeThumb.cy, UIR_OUTLINE);
}
m_pbmSelThumb->EndPaintInto(hDC);
}
}
}
void CDeviceView::OnPaint(HDC hDC)
{
HDC hBDC = NULL, hODC = NULL;
CBitmap *pbm = NULL;
if (!InRenderMode())
{
hODC = hDC;
pbm = CBitmap::Create(GetClientSize(), RGB(0, 0, 0), hDC);
if (pbm != NULL)
{
hBDC = pbm->BeginPaintInto();
if (hBDC != NULL)
hDC = hBDC;
}
}
// Black-fill first
SIZE fillsz = GetClientSize();
RECT fillrc = {0, 0, fillsz.cx, fillsz.cy};
FillRect(hDC, &fillrc, (HBRUSH)GetStockObject(BLACK_BRUSH));
if (m_pbmImage != NULL)
m_pbmImage->Blend(hDC);
BOOL bScroll = m_bScrollEnable && m_sb.m_hWnd;
int sdc = 0;
if (bScroll)
{
sdc = SaveDC(hDC);
OffsetViewportOrgEx(hDC, 0, -m_nScrollOffset + g_iListHeaderHeight, NULL);
}
else
if (m_bScrollEnable)
{
sdc = SaveDC(hDC);
OffsetViewportOrgEx(hDC, 0, g_iListHeaderHeight, NULL);
}
int miny = 0 + m_nScrollOffset;
int maxy = g_sizeImage.cy + m_nScrollOffset;
int t, nt = GetNumTexts();
for (t = 0; t < nt; t++)
{
CDeviceViewText *pText = m_arpText[t];
if (pText != NULL &&
!(pText->GetMinY() > maxy || pText->GetMaxY() < miny))
pText->OnPaint(hDC);
}
BOOL bCFGUIEdit = m_ui.m_uig.InEditMode();
BOOL bEitherEditMode = bCFGUIEdit;
int c, nc = GetNumControls();
for (c = 0; c < nc; c++)
if (m_arpControl[c] != NULL && m_arpControl[c]->HasOverlay() &&
(m_arpControl[c]->IsHighlighted()
)
&& (bEitherEditMode || m_arpControl[c]->IsMapped()))
m_arpControl[c]->DrawOverlay(hDC);
for (c = 0; c < nc; c++)
{
CDeviceControl *pControl = m_arpControl[c];
if (pControl != NULL && (bEitherEditMode || pControl->IsMapped()) &&
!(pControl->GetMinY() > maxy || pControl->GetMaxY() < miny))
pControl->OnPaint(hDC);
}
if (bScroll || m_bScrollEnable)
{
RestoreDC(hDC, sdc);
sdc = 0;
}
// Black fill the top portion if this is a list view
if (bScroll)
{
GetClientRect(&fillrc);
fillrc.bottom = g_iListHeaderHeight;
FillRect(hDC, &fillrc, (HBRUSH)GetStockObject(BLACK_BRUSH));
}
// Print out the headers
TCHAR tszHeader[MAX_PATH];
// Control column
if (m_arpText.GetSize())
{
CPaintHelper ph(m_ui.m_uig, hDC);
ph.SetElement(UIE_CALLOUT);
for (int i = 0; i < 2; i++)
{
// Check if there are two columns, break out the 2nd iteration if not 2 columns.
if (i == 1 && !(GetNumControls() > 1 &&
m_arpControl[0]->GetCalloutMaxRect().top == m_arpControl[1]->GetCalloutMaxRect().top))
break;
RECT rcheader;
if (m_arpText.GetSize())
{
rcheader = m_arpText[i]->GetRect();
rcheader.bottom -= rcheader.top;
rcheader.top = 0;
LoadString(g_hModule, IDS_LISTHEADER_CTRL, tszHeader, MAX_PATH);
DrawText(hDC, tszHeader, -1, &rcheader, DT_LEFT|DT_NOPREFIX|DT_CALCRECT);
if (rcheader.right > m_arpText[i]->GetRect().right)
rcheader.left -= rcheader.right - m_arpText[i]->GetRect().right;
DrawText(hDC, tszHeader, -1, &rcheader, DT_LEFT|DT_NOPREFIX);
// Action column
rcheader = m_arpControl[i]->GetCalloutMaxRect();
rcheader.bottom -= rcheader.top;
rcheader.top = 0;
LoadString(g_hModule, IDS_LISTHEADER_ACTION, tszHeader, MAX_PATH);
DrawText(hDC, tszHeader, -1, &rcheader, DT_CENTER|DT_NOPREFIX);
}
}
}
if (!InRenderMode())
{
if (pbm != NULL)
{
if (hBDC != NULL)
{
pbm->EndPaintInto(hBDC);
pbm->Draw(hODC);
}
delete pbm;
}
}
}
int CDeviceView::GetNumControls()
{
return m_arpControl.GetSize();
}
CDeviceControl *CDeviceView::GetControl(int nControl)
{
if (nControl >= 0 && nControl < GetNumControls())
return m_arpControl[nControl];
else
return NULL;
}
CBitmap *CDeviceView::GetImage(DVIMAGE dvi)
{
switch (dvi)
{
case DVI_IMAGE: return m_pbmImage;
case DVI_THUMB: return m_pbmThumb;
case DVI_SELTHUMB: return m_pbmSelThumb;
default:
return NULL;
}
}
void CDeviceView::OnMouseOver(POINT point, WPARAM wParam)
{
if (m_bScrollEnable && m_sb.m_hWnd)
point.y += m_nScrollOffset;
// Check if we are over a control
POINT adjPt = point;
if (m_bScrollEnable) adjPt.y -= g_iListHeaderHeight;
int c, nc = GetNumControls();
for (c = 0; c < nc; c++)
if (m_arpControl[c] != NULL && m_arpControl[c]->HitTest(adjPt) != DCHT_NOHIT)
{
m_arpControl[c]->OnMouseOver(adjPt);
return;
}
// Check if we are over a viewtext
nc = GetNumTexts();
for (c = 0; c < nc; c++)
if (m_arpText[c] != NULL && m_arpText[c]->HitTest(adjPt) != DCHT_NOHIT)
{
m_arpText[c]->OnMouseOver(adjPt);
return;
}
CFlexWnd::s_ToolTip.SetEnable(FALSE);
DEVICEUINOTIFY uin;
uin.msg = DEVUINM_MOUSEOVER;
uin.from = DEVUINFROM_VIEWWND;
uin.mouseover.point = point;
m_ui.Notify(uin);
}
void CDeviceView::OnClick(POINT point, WPARAM wParam, BOOL bLeft)
{
if (m_bScrollEnable && m_sb.m_hWnd)
point.y += m_nScrollOffset;
POINT adjPt = point;
if (m_bScrollEnable) adjPt.y -= g_iListHeaderHeight;
int c, nc = GetNumControls();
for (c = 0; c < nc; c++)
// adjPt is the adjust click point for scrolling list view
if (m_arpControl[c] != NULL && m_arpControl[c]->HitTest(adjPt) != DCHT_NOHIT)
{
m_arpControl[c]->OnClick(adjPt, bLeft);
return;
}
{
for (c = 0; c < GetNumTexts(); ++c)
if (m_arpControl[c] != NULL && m_arpText[c] != NULL)
{
RECT rc = m_arpText[c]->GetRect();
if (PtInRect(&rc, adjPt))
{
m_arpControl[c]->OnClick(adjPt, bLeft);
return;
}
}
}
// Send notification
DEVICEUINOTIFY uin;
uin.msg = DEVUINM_CLICK;
uin.from = DEVUINFROM_VIEWWND;
uin.click.bLeftButton = bLeft;
m_ui.Notify(uin);
}
void CDeviceView::OnDoubleClick(POINT point, WPARAM wParam, BOOL bLeft)
{
if (m_bScrollEnable && m_sb.m_hWnd)
point.y += m_nScrollOffset;
POINT adjPt = point;
if (m_bScrollEnable) adjPt.y -= g_iListHeaderHeight;
int c, nc = GetNumControls();
for (c = 0; c < nc; c++)
if (m_arpControl[c] != NULL && m_arpControl[c]->HitTest(adjPt) != DCHT_NOHIT)
{
m_arpControl[c]->OnClick(adjPt, bLeft, TRUE);
return;
}
for (c = 0; c < GetNumTexts(); ++c)
if (m_arpControl[c] != NULL && m_arpText[c] != NULL)
{
RECT rc = m_arpText[c]->GetRect();
if (PtInRect(&rc, adjPt))
{
m_arpControl[c]->OnClick(adjPt, bLeft, TRUE);
return;
}
}
DEVICEUINOTIFY uin;
uin.msg = DEVUINM_DOUBLECLICK;
uin.from = DEVUINFROM_VIEWWND;
uin.click.bLeftButton = bLeft;
m_ui.Notify(uin);
}
void CDeviceView::OnWheel(POINT point, WPARAM wParam)
{
if (!m_bScrollEnable) return;
if (m_sb.GetMin() == m_sb.GetMax()) return;
int nPage = MulDiv(m_sb.GetPage(), 9, 10) >> 1; // Half a page at a time
if ((int)wParam >= 0)
m_sb.AdjustPos(-nPage);
else
m_sb.AdjustPos(nPage);
m_nScrollOffset = m_sb.GetPos();
Invalidate();
}
BOOL CDeviceView::DoesCalloutExistForOffset(DWORD dwOfs)
{
return DoesCalloutOtherThanSpecifiedExistForOffset(NULL, dwOfs);
}
BOOL CDeviceView::DoesCalloutOtherThanSpecifiedExistForOffset(CDeviceControl *pOther, DWORD dwOfs)
{
int nc = GetNumControls();
for (int i = 0; i < nc; i++)
{
CDeviceControl *pControl = GetControl(i);
if (pControl == NULL || pControl == pOther)
continue;
if (!pControl->IsOffsetAssigned())
continue;
if (pControl->GetOffset() == dwOfs)
return TRUE;
}
return FALSE;
}
// This function returns the index of a control with the specified offset
int CDeviceView::GetIndexFromOfs(DWORD dwOfs)
{
for (int i = 0; i < GetNumControls(); ++i)
if (m_arpControl[i]->GetOffset() == dwOfs)
return i;
return -1;
}
int CDeviceView::GetViewIndex()
{
return m_ui.GetViewIndex(this);
}
BOOL CDeviceView::IsUnassignedOffsetAvailable()
{
DIDEVOBJSTRUCT os;
HRESULT hr = FillDIDeviceObjectStruct(os, m_ui.m_lpDID);
if (FAILED(hr))
return FALSE;
if (os.nObjects < 1)
return FALSE;
assert(os.pdoi);
if (!os.pdoi)
return FALSE;
for (int i = 0; i < os.nObjects; i++)
{
const DIDEVICEOBJECTINSTANCEW &o = os.pdoi[i];
if (!DoesCalloutExistForOffset(o.dwOfs))
return TRUE;
}
return FALSE;
}
CDeviceViewText *CDeviceView::AddText(
HFONT f, COLORREF t, COLORREF b, const RECT &r, LPCTSTR text)
{
CDeviceViewText *pText = NewText();
if (!pText)
return NULL;
pText->SetLook(f, t, b);
pText->SetRect(r);
pText->SetText(text);
return pText;
}
CDeviceViewText *CDeviceView::AddText(
HFONT f, COLORREF t, COLORREF b, const POINT &p, LPCTSTR text)
{
CDeviceViewText *pText = NewText();
if (!pText)
return NULL;
pText->SetLook(f, t, b);
pText->SetPosition(p);
pText->SetTextAndResizeTo(text);
return pText;
}
CDeviceViewText *CDeviceView::AddWrappedLineOfText(
HFONT f, COLORREF t, COLORREF b, LPCTSTR text)
{
CDeviceViewText *pText = NewText();
if (!pText)
return NULL;
pText->SetLook(f, t, b);
pText->SetPosition(m_ptNextWLOText);
pText->SetTextAndResizeToWrapped(text);
m_ptNextWLOText.y += pText->GetHeight();
return pText;
}
CDeviceViewText *CDeviceView::NewText()
{
CDeviceViewText *pText = new CDeviceViewText(m_ui, *this);
if (!pText)
return NULL;
m_arpText.SetAtGrow(m_arpText.GetSize(), pText);
return pText;
}
int CDeviceView::GetNumTexts()
{
return m_arpText.GetSize();
}
CDeviceViewText *CDeviceView::GetText(int nText)
{
if (nText < 0 || nText >= GetNumTexts())
return NULL;
return m_arpText[nText];
}
void CDeviceView::SetImage(CBitmap *&refpbm)
{
delete m_pbmImage;
m_pbmImage = refpbm;
refpbm = NULL;
MakeMissingImages();
Invalidate();
}
void CDeviceView::SetImagePath(LPCTSTR tszPath)
{
if (m_ptszImagePath)
free(m_ptszImagePath);
m_ptszImagePath = NULL;
if (tszPath)
m_ptszImagePath = _tcsdup(tszPath);
}
void CDeviceView::CalcDimensions()
{
// go through all texts and controls to find the max y coord
int max = g_sizeImage.cy - g_iListHeaderHeight;
int i = 0;
for (; i < GetNumTexts(); i++)
{
CDeviceViewText *pText = GetText(i);
if (!pText)
continue;
int ty = pText->GetMaxY();
if (ty > max)
max = ty;
}
for (i = 0; i < GetNumControls(); i++)
{
CDeviceControl *pControl = GetControl(i);
if (!pControl)
continue;
int cy = pControl->GetMaxY();
if (cy > max)
max = cy;
}
// set
m_nViewHeight = max;
m_nScrollOffset = 0;
// enable scrollbar if view height more than window size
if (m_nViewHeight > g_sizeImage.cy - g_iListHeaderHeight)
EnableScrollBar();
}
void CDeviceView::DisableScrollBar()
{
if (!m_sb.m_hWnd)
return;
m_sb.Destroy();
}
void CDeviceView::EnableScrollBar()
{
if (m_sb.m_hWnd)
return;
FLEXSCROLLBARCREATESTRUCT cs;
cs.dwSize = sizeof(cs);
cs.dwFlags = FSBF_VERT;
cs.min = 0;
cs.max = m_nViewHeight;
cs.page = g_sizeImage.cy - g_iListHeaderHeight;
cs.pos = m_nScrollOffset;
cs.hWndParent = m_hWnd;
cs.hWndNotify = m_hWnd;
RECT rect = {g_sizeImage.cx - DEFAULTVIEWSBWIDTH, g_iListHeaderHeight, g_sizeImage.cx, g_sizeImage.cy};
cs.rect = rect;
cs.bVisible = TRUE;
m_sb.SetColors(
m_ui.m_uig.GetBrushColor(UIE_SBTRACK),
m_ui.m_uig.GetBrushColor(UIE_SBTHUMB),
m_ui.m_uig.GetPenColor(UIE_SBBUTTON));
m_sb.Create(&cs);
}
LRESULT CDeviceView::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_PAINT:
m_bForcePaint = TRUE;
return CFlexWnd::WndProc(hWnd, msg, wParam, lParam);
case WM_FLEXVSCROLL:
{
int code = (int)wParam;
CFlexScrollBar *pSB = (CFlexScrollBar *)lParam;
if (!pSB)
return 0;
int nLine = 5;
int nPage = MulDiv(pSB->GetPage(), 9, 10);
switch (code)
{
case SB_LINEUP: pSB->AdjustPos(-nLine); break;
case SB_LINEDOWN: pSB->AdjustPos(nLine); break;
case SB_PAGEUP: pSB->AdjustPos(-nPage); break;
case SB_PAGEDOWN: pSB->AdjustPos(nPage); break;
case SB_THUMBTRACK: pSB->SetPos(pSB->GetThumbPos()); break;
}
m_nScrollOffset = pSB->GetPos();
Invalidate();
return 0;
}
case WM_FLEXHSCROLL:
assert(0);
default:
return CFlexWnd::WndProc(hWnd, msg, wParam, lParam);
}
}
void CDeviceView::ScrollToMakeControlVisible(const RECT &rc)
{
RECT viewrc;
if (!m_bScrollEnable)
return;
GetClientRect(&viewrc);
viewrc.bottom -= g_iListHeaderHeight;
viewrc.top += m_nScrollOffset;
viewrc.bottom += m_nScrollOffset;
// If scroll enabled, we scroll the view to make the control visible if not already so.
if (m_bScrollEnable && m_sb.m_hWnd &&
!(viewrc.left <= rc.left &&
viewrc.right >= rc.right &&
viewrc.top <= rc.top &&
viewrc.bottom >= rc.bottom))
{
// If the callout is below the view window, scroll so it shows up at the bottom of the window.
if (viewrc.bottom < rc.bottom)
m_sb.SetPos(m_sb.GetPos() + rc.bottom - viewrc.bottom);
else
m_sb.SetPos(rc.top);
m_nScrollOffset = m_sb.GetPos();
Invalidate();
}
}
void CDeviceView::SwapControls(int i, int j)
{
RECT rect;
CDeviceControl *pTmpControl;
CDeviceViewText *pTmpViewText;
pTmpControl = m_arpControl[i];
m_arpControl[i] = m_arpControl[j];
m_arpControl[j] = pTmpControl;
pTmpViewText = m_arpText[i];
m_arpText[i] = m_arpText[j];
m_arpText[j] = pTmpViewText;
// Swap the rect back so everything will display properly.
rect = m_arpControl[i]->GetCalloutMaxRect();
m_arpControl[i]->SetCalloutMaxRect(m_arpControl[j]->GetCalloutMaxRect());
m_arpControl[j]->SetCalloutMaxRect(rect);
rect = m_arpText[i]->GetRect();
m_arpText[i]->SetRect(m_arpText[j]->GetRect());
m_arpText[j]->SetRect(rect);
// Exchange the text rect width, so the correct width stays with the correct text.
RECT rc1 = m_arpText[i]->GetRect();
RECT rc2 = m_arpText[j]->GetRect();
// Store rc1's new width first
int iTempWidth = rc1.right - (rc2.right - rc2.left);
rc2.left = rc2.right - (rc1.right - rc1.left); // Adjust rc2's width
rc1.left = iTempWidth; // Adjust rc1's width
m_arpText[i]->SetRect(rc1);
m_arpText[j]->SetRect(rc2);
}
// Implements a simple selection sort algorithm to sort the control array and viewtext array.
// - iStart is the starting index, inclusive.
// - iEnd is the last index, exclusive.
void CDeviceView::SortCallouts(int iStart, int iEnd)
{
for (int i = iStart; i < iEnd - 1; ++i)
{
DWORD dwSmallestOfs = m_arpControl[i]->GetOffset();
int iSmallestIndex = i;
for (int j = i + 1; j < iEnd; ++j)
if (m_arpControl[j]->GetOffset() < dwSmallestOfs)
{
dwSmallestOfs = m_arpControl[j]->GetOffset();
iSmallestIndex = j;
}
// Swap the smallest element with i-th element.
if (iSmallestIndex != i)
SwapControls(i, iSmallestIndex);
}
}
void CDeviceView::SortAssigned(BOOL bSort)
{
// If less than 2 controls, no need for sorting.
if (m_arpControl.GetSize() < 2)
return;
int iCalloutX[2] = {m_arpControl[0]->GetMinX(), m_arpControl[1]->GetMinX()}; // Callout X for the two columns
// Sort the text array and control array.
if (bSort)
{
// First move all the assigned controls to the first n elements.
int iNextAssignedWriteIndex = 0;
for (int i = 0; i < m_arpControl.GetSize(); ++i)
if (m_arpControl[i]->HasAction())
{
// Swap the controls
SwapControls(i, iNextAssignedWriteIndex);
++iNextAssignedWriteIndex; // Increment the write index
}
// Sort the two parts now
SortCallouts(0, iNextAssignedWriteIndex);
SortCallouts(iNextAssignedWriteIndex, m_arpControl.GetSize());
} else
SortCallouts(0, m_arpControl.GetSize());
}
void CDeviceView::DoOnPaint(HDC hDC)
{
// Paint only if we have an update region.
if (GetUpdateRect(m_hWnd, NULL, FALSE) || m_bForcePaint)
OnPaint(hDC);
m_bForcePaint = FALSE;
}

View File

@@ -0,0 +1,143 @@
//-----------------------------------------------------------------------------
// File: cdeviceview.h
//
// Desc: CDeviceView is a window class derived from CFlexWnd. It represents
// the device view window in which the device and callouts are drawn.
// Each CDeviceView only represents one view. A device that has more
// than one view should have a corresponding number of CDeviceView for it.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifdef FORWARD_DECLS
enum DVIMAGE;
class CDeviceView;
#define DEFAULTVIEWSBWIDTH 11
#else // FORWARD_DECLS
#ifndef __CDEVICEVIEW_H__
#define __CDEVICEVIEW_H__
enum DVIMAGE {
DVI_IMAGE,
DVI_THUMB,
DVI_SELTHUMB
};
class CDeviceView : public CFlexWnd
{
private:
friend class CDeviceUI; // CDeviceUI has exclusive right to create/destroy views
friend class CDIDeviceActionConfigPage;
CDeviceView(CDeviceUI &ui);
~CDeviceView();
CDeviceUI &m_ui;
public:
// control information
int GetNumControls();
CDeviceControl *GetControl(int nControl);
CDeviceControl *GetControlFromOfs(DWORD dwOfs)
{ return GetControl(GetIndexFromOfs(dwOfs)); }
// text information
int GetNumTexts();
CDeviceViewText *GetText(int nText);
// text addition
CDeviceViewText *NewText();
CDeviceViewText *AddText(
HFONT, COLORREF, COLORREF, const RECT &, LPCTSTR text);
CDeviceViewText *AddText(
HFONT, COLORREF, COLORREF, const POINT &, LPCTSTR text);
CDeviceViewText *AddWrappedLineOfText(
HFONT, COLORREF, COLORREF, LPCTSTR text);
void SetImage(CBitmap *&refpbm);
void SetImagePath(LPCTSTR tszPath);
// imaging
CBitmap *GetImage(DVIMAGE dvi);
// editing
void Remove(CDeviceControl *pControl);
void RemoveAll(BOOL bUser = TRUE);
BOOL DoesCalloutOtherThanSpecifiedExistForOffset(CDeviceControl *, DWORD);
BOOL DoesCalloutExistForOffset(DWORD);
BOOL IsUnassignedOffsetAvailable();
int GetViewIndex();
int GetIndexFromOfs(DWORD dwOfs); // For writing to INI
void MakeMissingImages();
CDeviceControl *NewControl();
protected:
virtual void OnPaint(HDC hDC);
virtual void OnMouseOver(POINT point, WPARAM fwKeys);
virtual void OnClick(POINT point, WPARAM fwKeys, BOOL bLeft);
virtual void OnDoubleClick(POINT point, WPARAM fwKeys, BOOL bLeft);
virtual void OnWheel(POINT point, WPARAM wParam);
virtual LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
// helpers
void Unpopulate(BOOL bInternalOnly = FALSE);
// images/visualization
CBitmap *m_pbmImage, *m_pbmThumb, *m_pbmSelThumb;
LPTSTR m_ptszImagePath;
CBitmap *GrabViewImage();
LPCTSTR GetImagePath() { return m_ptszImagePath; }
// controls
CArray<CDeviceControl *, CDeviceControl *&> m_arpControl;
// text
CArray<CDeviceViewText *, CDeviceViewText *&> m_arpText;
POINT m_ptNextWLOText;
// Special painting
virtual void DoOnPaint(HDC hDC);
BOOL m_bForcePaint; // This indicates that we need painting even if GetUpdateRect returns FALSE.
// Sort assigned for keyboard devices
void SwapControls(int i, int j);
void SortAssigned(BOOL bSort);
void SortCallouts(int iStart, int iEnd);
// editting state machine
int m_SuperState, m_State, m_SubState;
int m_OldSuperState, m_OldState, m_OldSubState;
CDeviceControl *m_pControlContext;
// scrolling (vertical only)
BOOL m_bScrollEnable;
int m_nScrollOffset;
int m_nViewHeight;
public:
void EnableScrolling() {m_bScrollEnable = TRUE;}
void ScrollToMakeControlVisible(const RECT &rc);
void CalcDimensions();
private:
void DisableScrollBar();
void EnableScrollBar();
CFlexScrollBar m_sb;
};
#endif //__CDEVICEVIEW_H__
#endif // FORWARD_DECLS

View File

@@ -0,0 +1,191 @@
//-----------------------------------------------------------------------------
// File: cdeviceviewtext.cpp
//
// Desc: CDeviceViewText is a class representing a text string in the view
// window. It is used when the view type is a list view. CDeviceViewText
// will print the text of the control name, while CDeviceControl will
// print the text of the action assigned to that control.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
#include <string.h>
CDeviceViewText::CDeviceViewText(CDeviceUI &ui, CDeviceView &view) :
m_ui(ui), m_view(view),
m_hFont(NULL),
m_rgbText(RGB(255,255,255)),
m_rgbBk(RGB(0,0,0)),
m_bWrap(FALSE),
m_bClipped(FALSE),
m_ptszText(NULL)
{
m_rect.left = m_rect.top = m_rect.right = m_rect.bottom = 0;
}
CDeviceViewText::~CDeviceViewText()
{
if (m_ptszText)
free(m_ptszText);
m_ptszText = NULL;
}
void CDeviceViewText::SetLook(HFONT a, COLORREF b, COLORREF c)
{
m_hFont = a;
m_rgbText = b;
m_rgbBk = c;
Invalidate();
}
void CDeviceViewText::SetPosition(int x, int y)
{
int w = m_rect.right - m_rect.left;
int h = m_rect.bottom - m_rect.top;
m_rect.left = x;
m_rect.right = x + w;
m_rect.top = y;
m_rect.bottom = y + h;
Invalidate();
}
void CDeviceViewText::SetRect(const RECT &r)
{
m_rect = r;
CheckClipped();
Invalidate();
}
void CDeviceViewText::_SetText(LPCTSTR t)
{
if (m_ptszText)
free(m_ptszText);
if (t)
m_ptszText = AllocLPTSTR(t);
}
// Check if the text is clipped when printed and set flag appropriately.
void CDeviceViewText::CheckClipped()
{
RECT rect = m_rect;
HDC hDC = CreateCompatibleDC(NULL);
if (hDC != NULL)
{
HGDIOBJ hOld = NULL;
if (m_hFont)
hOld = SelectObject(hDC, m_hFont);
DrawText(hDC, m_ptszText, -1, &rect, DT_CALCRECT | DT_NOPREFIX | DT_LEFT);
if (m_hFont)
SelectObject(hDC, hOld);
DeleteDC(hDC);
}
if (rect.right > m_rect.right || rect.bottom > m_rect.bottom)
m_bClipped = TRUE;
else
m_bClipped = FALSE;
}
void CDeviceViewText::SetText(LPCTSTR t)
{
_SetText(t);
CheckClipped();
Invalidate(TRUE);
}
void CDeviceViewText::SetTextAndResizeTo(LPCTSTR t)
{
_SetText(t);
SIZE s = GetTextSize(m_ptszText, m_hFont);
m_rect.right = m_rect.left + s.cx;
m_rect.bottom = m_rect.top + s.cy;
CheckClipped();
Invalidate(TRUE);
}
void CDeviceViewText::SetTextAndResizeToWrapped(LPCTSTR t)
{
_SetText(t);
if (!m_ptszText)
{
m_rect.right = m_rect.left;
m_rect.bottom = m_rect.top;
Invalidate(TRUE);
return;
}
RECT rect = {m_rect.left, m_rect.top, g_sizeImage.cx, m_rect.top + 1};
HDC hDC = CreateCompatibleDC(NULL);
if (hDC != NULL)
{
HGDIOBJ hOld = NULL;
if (m_hFont)
hOld = SelectObject(hDC, m_hFont);
DrawText(hDC, m_ptszText, -1, &rect, DT_CALCRECT | DT_NOPREFIX | DT_WORDBREAK);
if (m_hFont)
SelectObject(hDC, hOld);
DeleteDC(hDC);
}
m_rect = rect;
m_bWrap = TRUE;
CheckClipped();
Invalidate(TRUE);
}
void CDeviceViewText::SetWrap(BOOL bWrap)
{
m_bWrap = bWrap;
Invalidate();
}
void CDeviceViewText::Invalidate(BOOL bForce)
{
if (m_ptszText || bForce)
m_view.Invalidate();
}
void CDeviceViewText::OnPaint(HDC hDC)
{
if (!m_ptszText)
return;
SetTextColor(hDC, m_rgbText);
SetBkColor(hDC, m_rgbBk);
SetBkMode(hDC, OPAQUE);
RECT rect = m_rect;
HGDIOBJ hOld = NULL;
if (m_hFont)
hOld = SelectObject(hDC, m_hFont);
DrawText(hDC, m_ptszText, -1, &rect, DT_NOPREFIX | (m_bWrap ? DT_WORDBREAK : 0) | DT_RIGHT | DT_END_ELLIPSIS);
if (m_hFont)
SelectObject(hDC, hOld);
}
// We will have to know the view's scrolling offset to adjust the tooltip's position.
void CDeviceViewText::OnMouseOver(POINT point)
{
// Tooltip only if the callout text is clipped.
if (m_bClipped)
{
TOOLTIPINITPARAM ttip;
ttip.hWndParent = GetParent(m_view.m_hWnd); // Parent is the page window.
ttip.iSBWidth = 0;
ttip.dwID = 0;
ttip.hWndNotify = m_view.m_hWnd;
ttip.tszCaption = GetText();
CFlexToolTip::UpdateToolTipParam(ttip);
} else
CFlexWnd::s_ToolTip.SetToolTipParent(NULL);
}
DEVCTRLHITRESULT CDeviceViewText::HitTest(POINT test)
{
if (PtInRect(&m_rect, test))
return DCHT_CAPTION;
return DCHT_NOHIT;
}

View File

@@ -0,0 +1,74 @@
//-----------------------------------------------------------------------------
// File: cdeviceviewtext.h
//
// Desc: CDeviceViewText is a class representing a text string in the view
// window. It is used when the view type is a list view. CDeviceViewText
// will print the text of the control name, while CDeviceControl will
// print the text of the action assigned to that control.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifdef FORWARD_DECLS
class CDeviceViewText;
#else // FORWARD_DECLS
#ifndef __CDEVICEVIEWTEXT_H__
#define __CDEVICEVIEWTEXT_H__
class CDeviceViewText
{
private:
friend class CDeviceView; // CDeviceView has exclusive right to create/destroy views
CDeviceViewText(CDeviceUI &ui, CDeviceView &view);
~CDeviceViewText();
CDeviceView &m_view;
CDeviceUI &m_ui;
public:
// set look/position/text
void SetLook(HFONT, COLORREF, COLORREF);
void SetRect(const RECT &r);
void SetPosition(int, int);
void SetPosition(POINT p) {SetPosition(p.x, p.y);}
void SetText(LPCTSTR);
void SetTextAndResizeTo(LPCTSTR);
void SetTextAndResizeToWrapped(LPCTSTR);
void SetWrap(BOOL bWrap = FALSE);
LPCTSTR GetText() { return m_ptszText; }
// get dimensions
RECT GetRect() {return m_rect;}
int GetHeight() {return m_rect.bottom - m_rect.top;}
int GetMinY() {return m_rect.top;}
int GetMaxY() {return m_rect.bottom;}
// hit testing (in coord's relative to view's origin)
DEVCTRLHITRESULT HitTest(POINT test);
void OnPaint(HDC);
void OnMouseOver(POINT point);
private:
void _SetText(LPCTSTR t);
void CheckClipped();
void Invalidate(BOOL bForce = FALSE);
HFONT m_hFont;
COLORREF m_rgbText, m_rgbBk;
RECT m_rect;
BOOL m_bWrap;
BOOL m_bClipped;
LPTSTR m_ptszText;
};
#endif //__CDEVICEVIEWTEXT_H__
#endif // FORWARD_DECLS

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,192 @@
//-----------------------------------------------------------------------------
// File: cdiacpage.h
//
// Desc: CDIDeviceActionConfigPage implements the page object used by the UI.
// A page covers the entire UI minus the device tabs and the bottons at
// the bottom. The information window, player combo-box, genre combo-
// box, action list tree, and device view window are all managed by
// the page.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifdef FORWARD_DECLS
class CDIDeviceActionConfigPage;
#else // FORWARD_DECLS
#ifndef __CDIACPAGE_H__
#define __CDIACPAGE_H__
// For WINMM.DLL
typedef MMRESULT (WINAPI *FUNCTYPE_timeSetEvent)(UINT, UINT, LPTIMECALLBACK, DWORD_PTR, UINT);
extern HINSTANCE g_hWinMmDLL;
extern FUNCTYPE_timeSetEvent g_fptimeSetEvent;
//implementation class
class CDIDeviceActionConfigPage : public IDIDeviceActionConfigPage, public CDeviceUINotify, public CFlexWnd
{
public:
//IUnknown fns
STDMETHOD (QueryInterface) (REFIID iid, LPVOID *ppv);
STDMETHOD_(ULONG, AddRef) ();
STDMETHOD_(ULONG, Release) ();
//IDirectInputActionConfigPage
STDMETHOD (Create) (DICFGPAGECREATESTRUCT *pcs);
STDMETHOD (Show) (LPDIACTIONFORMATW lpDiActFor);
STDMETHOD (Hide) ();
// layout edit mode
STDMETHOD (SetEditLayout) (BOOL bEditLayout);
// Set the info box text
STDMETHOD (SetInfoText) (int iCode);
// Unacquire and Reacquire the device for page's purposes
// (the configwnd needs to do this around SetActionMap() calls)
STDMETHOD (Unacquire) ();
STDMETHOD (Reacquire) ();
//construction/destruction
CDIDeviceActionConfigPage();
~CDIDeviceActionConfigPage();
// dialog window message handlers
/* BOOL OnInitDialog(HWND hWnd, HWND hwndFocus);
BOOL OnCommand(WPARAM wParam, LPARAM lParam);
LRESULT OnNotify(WPARAM wParam, LPARAM lParam);
void OnPaint(HDC hDC);
void OnClick(POINT point, WPARAM, BOOL bLeft);*/
protected:
virtual void OnInit();
virtual void OnPaint(HDC hDC);
virtual void OnClick(POINT point, WPARAM fwKeys, BOOL bLeft);
virtual void OnMouseOver(POINT point, WPARAM fwKeys);
virtual LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
enum CONFIGSTATE {CFGSTATE_NORMAL, CFGSTATE_ASSIGN};
// HWND m_hWnd; // handle to the page dialog window
LONG m_cRef; //reference count
LPDIACTIONFORMATW m_lpDiac;
DIDEVICEINSTANCEW m_didi;
LPDIRECTINPUTDEVICE8W m_lpDID;
CUIGlobals *m_puig;
IDIConfigUIFrameWindow *m_pUIFrame;
CONFIGSTATE m_State;
// device ui
CDeviceUI *m_pDeviceUI;
CDeviceControl *m_pCurControl;
virtual void DeviceUINotify(const DEVICEUINOTIFY &);
virtual BOOL IsControlMapped(CDeviceControl *);
// ui logic
void SetCurrentControl(CDeviceControl *pControl);
void NullAction(LPDIACTIONW lpac);
void UnassignControl(CDeviceControl *pControl);
friend void CallUnassignControl(CDeviceControl *pControl, LPVOID pVoid, BOOL bFixed);
void UnassignAction(LPDIACTIONW lpac);
void UnassignSpecificAction(LPDIACTIONW lpac);
void UnassignActionsAssignedTo(const GUID &guidInstance, DWORD dwOffset);
void AssignCurrentControlToAction(LPDIACTIONW lpac);
void ActionClick(LPDIACTIONW lpac);
void EnterAssignState();
void ExitAssignState();
void UnassignCallout();
void SetAppropriateDefaultText();
void GlobalUnassignControlAt(const GUID &, DWORD);
void SetControlAssignments();
void ShowCurrentControlAssignment();
CBitmap *m_pbmRelAxesGlyph;
CBitmap *m_pbmAbsAxesGlyph;
CBitmap *m_pbmButtonGlyph;
CBitmap *m_pbmHatGlyph;
CBitmap *m_pbmCheckGlyph;
CBitmap *m_pbmCheckGlyphDark;
CBitmap *m_pbmIB;
CBitmap *m_pbmIB2;
void InitResources();
void FreeResources();
RECT m_rectIB;
RECT m_rectIBLeft;
RECT m_rectIBRight;
LPTSTR m_tszIBText;
POINT m_ptIBOffset;
POINT m_ptIBOffset2;
RECT m_rectIBText;
void InitIB();
CViewSelWnd m_ViewSelWnd;
void DoViewSel();
CFlexTree m_Tree;
CFTItem *m_pRelAxesParent, *m_pAbsAxesParent, *m_pButtonParent, *m_pHatParent, *m_pUnknownParent;
void ClearTree();
void InitTree(BOOL bForceInit = FALSE);
DWORD m_dwLastControlType;
CFTItem *GetItemForActionAssignedToControl(CDeviceControl *pControl);
int GetNumItemLpacs(CFTItem *pItem);
LPDIACTIONW GetItemLpac(CFTItem *pItem, int i = 0);
typedef CArray<LPDIACTIONW, LPDIACTIONW &> RGLPDIACW;
// GetItemWithActionNameAndSemType returns an item with the specified action name and semantic type. NULL if none.
CFTItem *GetItemWithActionNameAndSemType(LPCWSTR acname, DWORD dwSemantic);
BOOL IsActionAssignedHere(int index);
// quick fix for offset->objid change:
void SetInvalid(LPDIACTIONW);
DWORD GetOffset(LPDIACTIONW);
void SetOffset(LPDIACTIONW, DWORD);
bidirlookup<DWORD, DWORD> offset_objid;
HRESULT InitLookup();
// dropdowns
CFlexComboBox m_UserNames, m_Genres;
// Information window
CFlexInfoBox m_InfoBox;
// Sort Assigned check box for keyboard devices
CFlexCheckBox m_CheckBox;
// device control
DWORD m_cbDeviceDataSize;
DWORD *m_pDeviceData[2];
int m_nOnDeviceData;
BOOL m_bFirstDeviceData;
void InitDevice();
void DeviceTimer();
static void CALLBACK DeviceTimerProc(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);
void DeviceDelta(DWORD *pData, DWORD *pOldData);
void AxisDelta(const DIDEVICEOBJECTINSTANCEW &doi, BOOL data, BOOL old);
void ButtonDelta(const DIDEVICEOBJECTINSTANCEW &doi, DWORD data, DWORD old);
void PovDelta(const DIDEVICEOBJECTINSTANCEW &doi, DWORD data, DWORD old);
void ActivateObject(const DIDEVICEOBJECTINSTANCEW &doi);
void DeactivateObject(const DIDEVICEOBJECTINSTANCEW &doi);
bidirlookup<DWORD, int> objid_avai;
typedef CArray<int, int &> AxisValueArray;
CArray<AxisValueArray, AxisValueArray &> m_AxisValueArray;
void StoreAxisDeltaAndCalcSignificance(const DIDEVICEOBJECTINSTANCEW &doi, DWORD data, DWORD olddata, BOOL &bSig, BOOL &bOldSig);
// page index
int m_nPageIndex;
};
#endif //__CDIACPAGE_H__
#endif // FORWARD_DECLS

View File

@@ -0,0 +1,272 @@
//-----------------------------------------------------------------------------
// File: cfguitrace.cpp
//
// Desc: Contains all trace functionalities used by the UI.
// Define __CFGUI_TRACE__TO_FILE to have output written to a file.
// Define __CFGUI_TRACE__TO_DEBUG_OUT to direct output to a debugger.
// These two symbols can coexist, and are defined in defines.h.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
#ifndef NTRACE
const int mindepth = 0;
static int depth = mindepth;
static int filedepth = 0;
static FILE *file = NULL;
__cfgui_out_filescope::__cfgui_out_filescope(bool bInternal)
: m_bInternal(bInternal)
{
#ifdef __CFGUI_TRACE__TO_FILE
static bool bFirst = true;
filedepth++;
if (filedepth == 1)
{
assert(file == NULL);
if (file == NULL)
file = fopen("c:\\cfguilog.txt", bFirst ? "w+t" : "a+t");
assert(file != NULL);
if (file != NULL)
{
if (bFirst)
{
time_t curtime;
time(&curtime);
LPSTR str = _strdup(ctime(&curtime));
if (str != NULL)
{
LPSTR last = str + strlen(str) - 1;
if (last >= str && *last == '\n')
*last = 0;
}
fprintf(file,
"\n"
"\n"
"\n"
"--------------------------------------------------------------------------------\n"
"DInput Mapper Device Configuration UI\n"
"New logfile session started at %s.\n"
"--------------------------------------------------------------------------------\n"
"\n"
, str);
free(str);
}
bFirst = false;
}
}
#endif
}
__cfgui_out_filescope::~__cfgui_out_filescope()
{
#ifdef __CFGUI_TRACE__TO_FILE
assert(filedepth > 0);
if (filedepth < 0)
filedepth = 0;
if (filedepth > 0)
{
filedepth--;
assert(file != NULL);
if (file != NULL)
{
if (filedepth == 0)
{
fclose(file);
file = NULL;
}
else if (!m_bInternal)
fflush(file);
}
}
#endif
}
static void __cfgui_out(LPCTSTR str)
{
#ifdef __CFGUI_TRACE__TO_FILE
assert(file != NULL);
if (file != NULL)
_ftprintf(file, str);
#endif
#ifdef __CFGUI_TRACE__TO_DEBUG_OUT
OutputDebugString(str);
#endif
}
__cfgui_tracescope::__cfgui_tracescope(LPCTSTR str)
{
if (str != NULL)
trace(str);
depth++;
}
__cfgui_tracescope::~__cfgui_tracescope()
{
depth--;
}
LPTSTR splitlines(LPTSTR);
/*void test(LPTSTR str)
{
LPTSTR orig = _tcsdup(str), str2 = _tcsdup(str);
static TCHAR buf[1024];
int i = 1;
for (LPTSTR token = splitlines(str2);
token != NULL;
token = splitlines(NULL), i++)
{
LPTSTR t = _tcsdup(token);
int len = _tcslen(t);
BOOL b = t[len - 1] == _T("\n")[0];
if (b)
t[len - 1] = _T("\0")[0];
_stprintf(buf, _T("%02d: \"%s\" (%s)\n"), i, t, BOOLSTR(b));
__cfgui_out(buf);
free(t);
}
free(str2);
free(orig);
}
*/
void __cfgui_trace(__cfgui_tracetype t, LPCTSTR format, ...)
{
__cfgui_out_filescope fs(true);
int i;
bool bError = t == __cfgui_tracetype_ERROR;
LPCTSTR errorprefix = _T("ERROR! ");
const int prefixlen = 8, depthbuflen = 1024, buflen = 4096;
static TCHAR prefixbuf[prefixlen + depthbuflen + 1] = _T("cfgUI: "), buf[buflen];
static LPTSTR depthbuf = prefixbuf + prefixlen;
static TCHAR space = _T(" ")[0];
static TCHAR zero = _T("\0")[0];
static TCHAR endl = _T("\n")[0];
static int last = -2;
static bool bendl = true;
if (last == -2)
{
for (i = 0; i < depthbuflen; i++)
depthbuf[i] = space;
depthbuf[i] = zero;
last = -1;
/*
test(_T("aopiwfoiefef\n\nwpoeifef\naefoie\n\n\nwpoeifwef asefeiof"));
test(_T("\npw\noiefpow ij e f owpiejf\n\n"));
test(_T("\n\npw\noiefpo wije\n\n \n\n\nfowpie jf \n"));
*/ }
if (last != -1)
{
depthbuf[last] = space;
}
int d = depth;
if (d < mindepth)
d = mindepth;
last = d * 4;
if (last >= depthbuflen)
last = depthbuflen - 1;
depthbuf[last] = zero;
va_list args;
va_start(args, format);
#ifdef WIN95
{
char *psz = NULL;
char szDfs[1024]={0};
strcpy(szDfs,format); // make a local copy of format string
while (psz = strstr(szDfs,"%p")) // find each %p
*(psz+1) = 'x'; // replace each %p with %x
_vstprintf(buf, szDfs, args); // use the local format string
}
#else
{
_vstprintf(buf, format, args);
}
#endif
va_end(args);
LPTSTR tempbuf = _tcsdup(buf);
bool doprefix = bendl;
for (LPTSTR token = splitlines(tempbuf);
token != NULL;
token = splitlines(NULL))
{
if (doprefix)
__cfgui_out(depthbuf/*prefixbuf*/);
if (bError && doprefix)
__cfgui_out(errorprefix);
__cfgui_out(token);
bendl = token[_tcslen(token) - 1] == endl;
doprefix = bendl;
}
free(tempbuf);
}
LPTSTR splitlines(LPTSTR split)
{
static LPTSTR str = NULL;
static int last = 0;
static TCHAR save = _T("!")[0];
static TCHAR newline = _T("\n")[0], zero = _T("\0")[0];
if (split != NULL)
str = split;
else
{
if (str == NULL)
return NULL;
str[last] = save;
str += last;
}
if (str[0] == zero)
{
str = NULL;
return NULL;
}
LPCTSTR at = str, f = _tcschr(at, newline);
last = f ? f - at + 1: _tcslen(at);
save = str[last];
str[last] = zero;
return str;
}
#endif

View File

@@ -0,0 +1,127 @@
//-----------------------------------------------------------------------------
// File: cfguitrace.h
//
// Desc: Contains all trace functionalities used by the UI.
// Define __CFGUI_TRACE__TO_FILE to have output written to a file.
// Define __CFGUI_TRACE__TO_DEBUG_OUT to direct output to a debugger.
// These two symbols can coexist, and are defined in defines.h.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __CFGUI_TRACE_H__
#define __CFGUI_TRACE_H__
#ifdef UNICODE
#define _tfWSTR _T("%s")
#define _tfSTR _T("%S")
#else
#define _tfWSTR _T("%S")
#define _tfSTR _T("%s")
#endif
enum __cfgui_tracetype {
__cfgui_tracetype_ERROR,
__cfgui_tracetype_INFO,
};
#ifdef NTRACE
#define tracescope(t,s) (void(0))
#define etrace(a) (void(0))
#define etrace1(a,b) (void(0))
#define etrace2(a,b,c) (void(0))
#define etrace3(a,b,c,d) (void(0))
#define etrace4(a,b,c,d,e) (void(0))
#define etrace5(a,b,c,d,e,f) (void(0))
#define etrace6(a,b,c,d,e,f,g) (void(0))
#define etrace7(a,b,c,d,e,f,g,h) (void(0))
#define trace(a) (void(0))
#define trace1(a,b) (void(0))
#define trace2(a,b,c) (void(0))
#define trace3(a,b,c,d) (void(0))
#define trace4(a,b,c,d,e) (void(0))
#define trace5(a,b,c,d,e,f) (void(0))
#define trace6(a,b,c,d,e,f,g) (void(0))
#define trace7(a,b,c,d,e,f,g,h) (void(0))
#define traceDWORD(v) (void(0))
#define traceUINT(v) (void(0))
#define traceLONG(v) (void(0))
#define traceHEX(v) (void(0))
#define traceHEXPTR(v) (void(0))
#define traceWSTR(v) (void(0))
#define traceSTR(v) (void(0))
#define traceTSTR(v) (void(0))
#define traceGUID(v) (void(0))
#define traceBOOL(v) (void(0))
#define tracePOINT(v) (void(0))
#define traceSIZE(v) (void(0))
#define traceRECT(v) (void(0))
#define traceRECTDIM(v) (void(0))
#define traceSUPERSTR(v) (void(0))
#else
void __cfgui_trace(__cfgui_tracetype, LPCTSTR, ...);
class __cfgui_out_filescope
{
friend class __cfgui_tracescope;
__cfgui_out_filescope(bool bInternal = false);
~__cfgui_out_filescope();
friend void __cfgui_trace(__cfgui_tracetype, LPCTSTR, ...);
bool m_bInternal;
};
class __cfgui_tracescope
{
__cfgui_out_filescope fs;
public:
__cfgui_tracescope(LPCTSTR);
~__cfgui_tracescope();
};
#define tracescope(t,s) __cfgui_tracescope t(s)
#define etrace(a) __cfgui_trace(__cfgui_tracetype_ERROR, a)
#define etrace1(a,b) __cfgui_trace(__cfgui_tracetype_ERROR, a,b)
#define etrace2(a,b,c) __cfgui_trace(__cfgui_tracetype_ERROR, a,b,c)
#define etrace3(a,b,c,d) __cfgui_trace(__cfgui_tracetype_ERROR, a,b,c,d)
#define etrace4(a,b,c,d,e) __cfgui_trace(__cfgui_tracetype_ERROR, a,b,c,d,e)
#define etrace5(a,b,c,d,e,f) __cfgui_trace(__cfgui_tracetype_ERROR, a,b,c,d,e,f)
#define etrace6(a,b,c,d,e,f,g) __cfgui_trace(__cfgui_tracetype_ERROR, a,b,c,d,e,f,g)
#define etrace7(a,b,c,d,e,f,g,h) __cfgui_trace(__cfgui_tracetype_ERROR, a,b,c,d,e,f,g,h)
#define trace(a) __cfgui_trace(__cfgui_tracetype_INFO, a)
#define trace1(a,b) __cfgui_trace(__cfgui_tracetype_INFO, a,b)
#define trace2(a,b,c) __cfgui_trace(__cfgui_tracetype_INFO, a,b,c)
#define trace3(a,b,c,d) __cfgui_trace(__cfgui_tracetype_INFO, a,b,c,d)
#define trace4(a,b,c,d,e) __cfgui_trace(__cfgui_tracetype_INFO, a,b,c,d,e)
#define trace5(a,b,c,d,e,f) __cfgui_trace(__cfgui_tracetype_INFO, a,b,c,d,e,f)
#define trace6(a,b,c,d,e,f,g) __cfgui_trace(__cfgui_tracetype_INFO, a,b,c,d,e,f,g)
#define trace7(a,b,c,d,e,f,g,h) __cfgui_trace(__cfgui_tracetype_INFO, a,b,c,d,e,f,g,h)
#define traceDWORD(v) trace1(_T(#v) _T(" = %u\n"), v)
#define traceUINT(v) trace1(_T(#v) _T(" = %u\n"), v)
#define traceLONG(v) trace1(_T(#v) _T(" = %d\n"), v)
#define traceHEX(v) trace1(_T(#v) _T(" = 0x%08x\n"), v)
#define traceHEXPTR(v) trace1(_T(#v) _T(" = 0x%p\n"), v)
#define traceWSTR(v) traceTSTR(v)
#define traceSTR(v) traceTSTR(v)
#define traceTSTR(v) trace1(_T(#v) _T(" = %s\n"), QSAFESTR(v))
#define traceGUID(v) trace1(_T(#v) _T(" = %s\n"), GUIDSTR(v))
#define traceBOOL(v) trace1(_T(#v) _T(" = %s\n"), BOOLSTR(v))
#define tracePOINT(v) trace1(_T(#v) _T(" = %s\n"), POINTSTR(v))
#define traceSIZE(v) trace1(_T(#v) _T(" = %s\n"), SIZESTR(v))
#define traceRECT(v) trace1(_T(#v) _T(" = %s\n"), RECTSTR(v))
#define traceRECTDIM(v) trace1(_T(#v) _T(" = %s\n"), RECTDIMSTR(v))
#define traceSUPERSTR(v) trace1(_T(#v) _T(" = %s\n"), SUPERSTR(v))
#endif
#endif //__CFGUI_TRACE_H__

View File

@@ -0,0 +1,260 @@
//-----------------------------------------------------------------------------
// File: cfrmwrk.cpp
//
// Desc: CDirectInputActionFramework is the outer-most layer of the UI. It
// contains everything else. Its functionality is provided by one
// method: ConfigureDevices.
//
// InternalConfigureDevices is called by the CDirectInputActionFramework
// class. This function actually contains the initialization code and
// the message pump for the UI.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
//QueryInterface
STDMETHODIMP CDirectInputActionFramework::QueryInterface(REFIID iid, LPVOID* ppv)
{
//null the out param
*ppv = NULL;
if ((iid == IID_IUnknown) || (iid == IID_IDIActionFramework))
{
*ppv = this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
//AddRef
STDMETHODIMP_(ULONG) CDirectInputActionFramework::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
//Release
STDMETHODIMP_(ULONG) CDirectInputActionFramework::Release()
{
if (InterlockedDecrement(&m_cRef) == 0)
{
delete this;
return 0;
}
return m_cRef;
}
// Manages auto loading/unloading WINMM.DLL
// There will only be one instance of this class: inside InternalConfigureDevicees.
class CWinMmLoader
{
public:
CWinMmLoader()
{
if (!g_hWinMmDLL)
{
g_hWinMmDLL = LoadLibrary(_T("WINMM.DLL"));
if (g_hWinMmDLL)
{
*(FARPROC*)(&g_fptimeSetEvent) = GetProcAddress(g_hWinMmDLL, "timeSetEvent");
}
}
}
~CWinMmLoader()
{
if (g_hWinMmDLL)
{
/*
* Make sure no new callbacks can get scheduled then sleep to
* allow any pending ones to complete.
*/
g_fptimeSetEvent = NULL;
Sleep( 40 );
FreeLibrary(g_hWinMmDLL);
g_hWinMmDLL = NULL;
}
}
};
// internal, which api wraps around
static HRESULT InternalConfigureDevices(LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
LPDICONFIGUREDEVICESPARAMSW lpdiCDParams,
DWORD dwFlags,
LPVOID pvRefData)
{
tracescope(__ts, _T("InternalConfigureDevices()\n"));
CWinMmLoader g_WinMmLoadingHelper; // Automatically call LoadLibrary and FreeLibrary on WINMM.DLL
// check that we're at least 256 colors
HDC hMemDC = CreateCompatibleDC(NULL);
if (hMemDC == NULL)
{
etrace(_T("Can't get a DC! Exiting.\n"));
return E_FAIL;
}
int bpp = GetDeviceCaps(hMemDC, BITSPIXEL);
DeleteDC(hMemDC);
if (bpp < 8)
{
etrace1(_T("Screen is not at least 8bpp (bpp = %d)\n"), bpp);
return E_FAIL;
}
// do it...
{
// create the globals
CUIGlobals uig(
dwFlags,
lpdiCDParams->lptszUserNames,
lpdiCDParams->dwcFormats,
lpdiCDParams->lprgFormats,
&(lpdiCDParams->dics),
lpdiCDParams->lpUnkDDSTarget,
lpdiCallback,
pvRefData
);
HRESULT hr = uig.GetInitResult();
if (FAILED(hr))
{
etrace(_T("CUIGlobals.Init() failed\n"));
return hr;
}
// make sure the flexwnd window class is registered only during possible use
{
struct flexwndscope {
flexwndscope(CUIGlobals &uig) : m_uig(uig) {CFlexWnd::RegisterWndClass(m_uig.GetInstance());}
~flexwndscope() {CFlexWnd::UnregisterWndClass(m_uig.GetInstance());}
CUIGlobals &m_uig;
} scope(uig);
// create the main window
CConfigWnd cfgWnd(uig);
if (!cfgWnd.Create(lpdiCDParams->hwnd))
{
etrace(_T("Failed to create main window\n"));
return E_FAIL;
}
// Initialize the shared tooltip object.
RECT rc = {0, 0, 0, 0};
CFlexWnd::s_ToolTip.Create(cfgWnd.m_hWnd, rc, TRUE);
if (!CFlexWnd::s_ToolTip.m_hWnd)
{
etrace(_T("Failed to create tooltip window\n"));
return E_FAIL;
}
::ShowWindow(CFlexWnd::s_ToolTip.m_hWnd, SW_HIDE); // Hide window by default
// enter message loop
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
// If this is a message for the parent window (game window), only dispatch if it's WM_PAINT.
if (!cfgWnd.InRenderMode() && msg.hwnd == lpdiCDParams->hwnd && msg.message != WM_PAINT)
continue;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
CFlexWnd::s_ToolTip.Destroy();
return uig.GetFinalResult();
}
}
BOOL AreAcForsGood(LPDIACTIONFORMATW lpAcFors, DWORD dwNumAcFors)
{
if (lpAcFors == NULL)
return FALSE;
if (dwNumAcFors < 1)
return FALSE;
if (lpAcFors->dwNumActions == 0)
return FALSE;
return TRUE;
}
//ConfigureDevices
STDMETHODIMP CDirectInputActionFramework::ConfigureDevices(
LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
LPDICONFIGUREDEVICESPARAMSW lpdiCDParams,
DWORD dwFlags,
LPVOID pvRefData)
{
tracescope(__ts,_T("CDirectInputActionFramework::ConfigureDevices()\n"));
trace(_T("\nConfigureDevices() called...\n\n"));
// check parameters
if (lpdiCDParams == NULL)
{
etrace(_T("NULL params structure passed to ConfigureDevices()\n"));
return E_INVALIDARG;
}
// save passed params in case we change 'em
LPDIACTIONFORMATW lpAcFors = lpdiCDParams->lprgFormats;
DWORD dwNumAcFors = lpdiCDParams->dwcFormats;
#ifdef CFGUI__FORCE_GOOD_ACFORS
if (!AreAcForsGood(lpdiCDParams->lprgFormats, lpdiCDParams->dwcFormats))
{
etrace(_T("Passed ActionFormats aren't good... Using GetTestActionFormats() (just 2 of them).\n"));
lpdiCDParams->dwcFormats = 2;
lpdiCDParams->lprgFormats = GetTestActionFormats();
}
#endif
HRESULT hr = InternalConfigureDevices(lpdiCallback, lpdiCDParams, dwFlags, pvRefData);
// restore passed params in case changed
lpdiCDParams->lprgFormats = lpAcFors;
lpdiCDParams->dwcFormats = dwNumAcFors;
trace(_T("\n"));
if (FAILED(hr))
etrace1(_T("ConfigureDevices() failed, returning 0x%08x\n"), hr);
else
trace1(_T("ConfigureDevices() suceeded, returning 0x%08x\n"), hr);
trace(_T("\n"));
return hr;
}
//constructor
CDirectInputActionFramework::CDirectInputActionFramework()
{
//set ref count
m_cRef = 1;
}
//destructor
CDirectInputActionFramework::~CDirectInputActionFramework()
{
// not necessary to cleanup action format here
}

View File

@@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
// File: cfrmwrk.h
//
// Desc: CDirectInputActionFramework is the outer-most layer of the UI. It
// contains everything else. Its functionality is provided by one
// method: ConfigureDevices.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef _CFRMWRK_H
#define _CFRMWRK_H
//framework implementation class
class CDirectInputActionFramework : public IDirectInputActionFramework
{
public:
//IUnknown fns
STDMETHOD (QueryInterface) (REFIID iid, LPVOID *ppv);
STDMETHOD_(ULONG, AddRef) ();
STDMETHOD_(ULONG, Release) ();
//own fns
STDMETHOD (ConfigureDevices) (LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
LPDICONFIGUREDEVICESPARAMSW lpdiCDParams,
DWORD dwFlags,
LPVOID pvRefData);
//construction / destruction
CDirectInputActionFramework();
~CDirectInputActionFramework();
protected:
//reference count
LONG m_cRef;
};
#endif // _CFRMWRK_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,102 @@
//-----------------------------------------------------------------------------
// File: common.hpp
//
// Desc: Master header file used by the UI. Good candidate for pre-compiled
// header.
//
// Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __CFGUI_COMMON_H__
#define __CFGUI_COMMON_H__
// custom/local defines
#include "defines.h"
// windows/system includes
#include <windows.h>
#include <objbase.h>
#include <winnls.h>
#include <commdlg.h>
#include <mmsystem.h>
#include <tchar.h>
// standard includes
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#include <string.h>
#include <process.h>
#include <time.h>
#include <assert.h>
// directx includes
#include <dinput.h>
#include <ddraw.h>
#include <d3d8.h>
#include <d3dx8tex.h>
// guids include
#include "ourguids.h"
// resource include
#include "dicfgres.h"
// constants include
#include "constants.h"
// main module include
#include "main.h"
// collections includes
#include "collections.h"
#include "bidirlookup.h"
// util includes
#include "cbitmap.h"
#include "cyclestr.h"
#include "useful.h"
#include "usefuldi.h"
#include "ltrace.h"
#include "cfguitrace.h"
#include "privcom.h"
// registry util include
#include "registry.h"
// flexwnd includes
#include "flexmsg.h"
#include "flexwnd.h"
#include "flexscrollbar.h"
#include "flextree.h"
#include "flexlistbox.h"
#include "flexcombobox.h"
#include "flextooltip.h"
#include "flexinfobox.h"
#include "flexcheckbox.h"
#include "flexmsgbox.h"
// uiglobals include
#include "uiglobals.h"
// interface includes
#include "iuiframe.h"
#include "idiacpage.h"
#include "ifrmwrk.h"
// class factory includes
#include "iclassfact.h"
#include "ipageclassfact.h"
// framework class/module includes
#include "configwnd.h"
#include "cfrmwrk.h"
// page class/module includes
#include "pagecommon.h"
#endif //__CFGUI_COMMON_H__

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,248 @@
//-----------------------------------------------------------------------------
// File: configwnd.h
//
// Desc: CConfigWnd is derived from CFlexWnd. It implements the top-level
// UI window which all other windows are descendents of.
//
// Functionalities handled by CConfigWnd are device tabs, Reset, Ok,
// and Cancel buttons.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __CONFIGWND_H__
#define __CONFIGWND_H__
#define PAGETYPE IDIDeviceActionConfigPage
#define NUMBUTTONS 3
class CMouseTrap : public CFlexWnd
{
HWND m_hParent;
public:
CMouseTrap() : m_hParent(NULL) { }
HWND Create(HWND hParent = NULL, BOOL bInRenderMode = TRUE);
protected:
virtual BOOL OnEraseBkgnd(HDC hDC) {return TRUE;}
virtual void OnPaint(HDC hDC) {}
virtual void OnRender(BOOL bInternalCall = FALSE) {}
};
// Each device is represented by an ELEMENT object that is managed by
// CConfigWnd.
struct ELEMENT {
ELEMENT() : nCurUser(-1), pPage(NULL), lpDID(NULL) {tszCaption[0] = 0;}
// everything's cleaned up in CConfigWnd::ClearElement();
DIDEVICEINSTANCEW didi;
PAGETYPE *pPage;
HWND hWnd;
BOOL bCalc;
RECT rect, textrect;
TCHAR tszCaption[MAX_PATH];
LPDIRECTINPUTDEVICE8W lpDID;
// the map of acfors contains an acfor for each genre/username
// that has been used so far on this device. the dword represents
// the genre username as follows: the hiword is the index of the
// genre per uiglobals. the loword is the index of the username
// per uiglobals.
CMap<DWORD, DWORD &, LPDIACTIONFORMATW, LPDIACTIONFORMATW &> AcForMap;
#define MAP2GENRE(m) (int(((m) & 0xffff0000) >> 16))
#define MAP2USER(m) (int((m) & 0x0000ffff))
#define GENREUSER2MAP(g,u) \
( \
((((DWORD)(nGenre)) & 0xffff) << 16) | \
(((DWORD)(nUser)) & 0xffff) \
)
// this function simply returns the corresponding entry in the
// map if it already exists. otherwise, it creates a copy for
// this entry from the masteracfor and calls buildactionmap on
// it with the appropriate username.
// bHwDefault flag is added to properly support Reset button. BuildActionMap must be
// called with the flag to get hardware default mapping, so we need this parameter.
LPDIACTIONFORMATW GetAcFor(int nGenre, int nUser, BOOL bHwDefault = FALSE);
// we need to keep track of the current user per-element
int nCurUser;
// we need a pointer to the uiglobals in order to correspond
// user indexes to the actual string
CUIGlobals *pUIGlobals;
// this function will be called in CConfigWnd::ClearElement to
// free all the actionformats from the map
void FreeMap();
// Applies all the acfor's in the map
void Apply();
};
typedef CArray<ELEMENT, ELEMENT &> ELEMENTARRAY;
// CConfigWnd needs to expose methods for child windows to notify it.
class CConfigWnd : public CFlexWnd, public IDIConfigUIFrameWindow
{
public:
CConfigWnd(CUIGlobals &uig);
~CConfigWnd();
BOOL Create(HWND hParent);
static void SetForegroundWindow();
LPDIRECTINPUTDEVICE8W RenewDevice(GUID &GuidInstance);
BOOL EnumDeviceCallback(const DIDEVICEINSTANCEW *lpdidi);
void EnumDeviceCallbackAssignUser(const DIDEVICEINSTANCEW *lpdidi, DWORD *pdwOwner);
CUIGlobals &m_uig;
// IDIConfigUIFrameWindow implementation...
// Reset Entire Configuration
STDMETHOD (Reset) ();
// Assignment Querying. GuidInstance is the guid of the device initiating the query.
STDMETHOD (QueryActionAssignedAnywhere) (GUID GuidInstance, int i);
// Genre Control
STDMETHOD_(int, GetNumGenres) ();
STDMETHOD (SetCurGenre) (int i);
STDMETHOD_(int, GetCurGenre) ();
// User Control
STDMETHOD_(int, GetNumUsers) ();
STDMETHOD (SetCurUser) (int nPage, int nUser);
STDMETHOD_(int, GetCurUser) (int nPage);
// ActionFormat Access
STDMETHOD (GetActionFormatFromInstanceGuid) (LPDIACTIONFORMATW *lplpAcFor, REFGUID);
// Main HWND Access
STDMETHOD_(HWND, GetMainHWND) ();
protected:
// overrides
virtual void OnRender(BOOL bInternalCall = FALSE);
virtual LRESULT OnCreate(LPCREATESTRUCT lpCreateStruct);
virtual void OnPaint(HDC hDC);
virtual void OnMouseOver(POINT point, WPARAM fwKeys);
virtual void OnClick(POINT point, WPARAM fwKeys, BOOL bLeft);
virtual void OnDestroy();
virtual LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
#define CFGWND_INIT_REINIT 1
#define CFGWND_INIT_RESET 2
BOOL Init(DWORD dwInitFlags = 0);
DWORD m_dwInitFlags;
BOOL m_bCreated;
int AddToList(const DIDEVICEINSTANCEW *lpdidi, BOOL bReset = FALSE);
void ClearList();
void PlacePages();
void GetPageRect(RECT &rect, BOOL bTemp = FALSE);
void Render(BOOL bInternalCall = FALSE);
ELEMENTARRAY m_Element;
ELEMENT m_InvalidElement;
int m_CurSel;
int GetNumElements();
ELEMENT &GetElement(int i);
void ClearElement(int i, BOOL bReset = FALSE);
void ClearElement(ELEMENT &e, BOOL bReset = FALSE);
BOOL m_bScrollTabs, m_bScrollTabsLeft, m_bScrollTabsRight;
int m_nLeftTab;
RECT m_rectSTLeft, m_rectSTRight;
void ScrollTabs(int);
LPDIRECTINPUTDEVICE8W CreateDevice(GUID &guid);
BOOL m_bNeedRedraw;
CFlexMsgBox m_MsgBox;
LPDIACTIONFORMATW GetCurAcFor(ELEMENT &e);
int m_nCurGenre;
IClassFactory *m_pPageFactory;
HINSTANCE m_hPageFactoryInst;
PAGETYPE *CreatePageObject(int nPage, const ELEMENT &e, HWND &refhChildWnd);
void DestroyPageObject(PAGETYPE *&pPage);
LPDIRECTINPUT8W m_lpDI;
RECT m_rectTopGradient, m_rectBottomGradient;
CBitmap *m_pbmTopGradient, *m_pbmBottomGradient;
BOOL m_bHourGlass; // Set when the cursor should be an hourglass
typedef struct BUTTON {
BUTTON() {CopyStr(tszCaption, _T(""), MAX_PATH);}
RECT rect;
TCHAR tszCaption[MAX_PATH];
SIZE textsize;
RECT textrect;
} BUTTON;
BUTTON m_Button[NUMBUTTONS];
enum {
BUTTON_RESET = 0,
BUTTON_CANCEL,
BUTTON_OK,
};
SIZE GetTextSize(LPCTSTR tszText);
void CalcTabs();
void CalcButtons();
void InitGradients();
void SelTab(int);
void FireButton(int);
void ShowPage(int);
void HidePage(int);
HDC GetRenderDC();
void ReleaseRenderDC(HDC &phDC);
void Create3DBitmap();
void Copy3DBitmapToSurface3D();
void CallRenderCallback();
IDirectDrawSurface *m_pSurface;
IDirect3DSurface8 *m_pSurface3D;
D3DFORMAT m_SurfFormat;
UINT m_uiPixelSize; // Size of a pixel in byte for the format we are using
CBitmap *m_pbmPointerEraser;
CBitmap *m_pbm3D;
LPVOID m_p3DBits;
BOOL m_bRender3D;
POINT m_ptTest;
void MapBitmaps(HDC);
BOOL m_bBitmapsMapped;
BOOL m_bAllowEditLayout;
BOOL m_bEditLayout;
void ToggleLayoutEditting();
CMouseTrap m_MouseTrap;
// Timer
static void CALLBACK TimerProc(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);
HRESULT Apply();
// GuidInstance is the guid of the device initiating the query.
BOOL IsActionAssignedAnywhere(GUID GuidInstance, int nActionIndex);
void Unacquire();
void Reacquire();
};
#endif //__CONFIGWND_H__

View File

@@ -0,0 +1,29 @@
//-----------------------------------------------------------------------------
// File: constants.cpp
//
// Desc: Contains all constants used by the UI.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
const SIZE g_sizeThumb = {64, 64};
const SIZE g_sizeImage = {430, 310};
const POINT g_ptViewOrigin = {13, 13};
const RECT g_UserNamesTitleRect = {9,120,190,132};
const RECT g_UserNamesRect = {9,137,190,364};
const RECT g_GenresTitleRect = {9,156,190,167};
const RECT g_GenresRect = {9,172,190,379};
const RECT g_InfoWndRect = {9, 10, 190, 120};
const RECT g_ViewRect = {200,10,630,320};
const RECT g_CheckBoxRect = {350, 335, 475, 355};
const int g_iListHeaderHeight = 30;
const int g_iResetMsgBoxWidth = 200;
const int g_iResetMsgBoxHeight = 60;
LPCTSTR g_tszUnassignedControlCaption = _T("_ _ _ ");
const RECT g_TreeTitleRect = {9,192,190,203};
const RECT g_TreeRect = {10,208,189,417};

View File

@@ -0,0 +1,32 @@
//-----------------------------------------------------------------------------
// File: constants.h
//
// Desc: Contains all constants used by the UI.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __CFGUI_CONSTANTS_H__
#define __CFGUI_CONSTANTS_H__
#define MINLISTVIEWCALLOUTWIDTH 70
extern const SIZE g_sizeThumb;
extern const SIZE g_sizeImage;
extern const POINT g_ptViewOrigin;
extern const RECT g_ViewRect;
extern const RECT g_CheckBoxRect;
extern const RECT g_InfoWndRect;
extern const RECT g_UserNamesRect;
extern const RECT g_UserNamesTitleRect;
extern const RECT g_GenresRect;
extern const RECT g_GenresTitleRect;
extern LPCTSTR g_tszUnassignedControlCaption;
extern const RECT g_TreeTitleRect;
extern const RECT g_TreeRect;
extern const int g_iListHeaderHeight;
extern const int g_iResetMsgBoxWidth;
extern const int g_iResetMsgBoxHeight;
#endif //__CFGUI_CONSTANTS_H__

View File

@@ -0,0 +1,173 @@
//-----------------------------------------------------------------------------
// File: cyclestr.cpp
//
// Desc: Implements a circular queue that provides space to hold a string
// without repeatedly allocating and deallocating memory. This is
// only for short-term use such as outputting debug message to
// ensure that the same buffer is not used at more than one place
// simultaneously.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
static const int g_cycles = 16;
static const int g_cyclelen = 256;
LPTSTR getcyclestr()
{
static int on = g_cycles;
static TCHAR cycle[g_cycles][g_cyclelen];
on++;
if (on >= g_cycles)
on = 0;
return cycle[on];
}
inline static void cap(LPTSTR c)
{
c[g_cyclelen - 1] = 0;
}
#define SAFESTR_noconv \
if (str) \
return str; \
else \
return _T("NULL");
#define SAFESTR_conv \
LPTSTR c = getcyclestr(); \
CopyStr(c, str, g_cyclelen); \
cap(c); \
return SAFESTR(c);
LPCTSTR SAFESTR(LPCWSTR str)
{
#ifdef UNICODE
SAFESTR_noconv
#else
SAFESTR_conv
#endif
}
LPCTSTR SAFESTR(LPCSTR str)
{
#ifdef UNICODE
SAFESTR_conv
#else
SAFESTR_noconv
#endif
}
#define QSAFESTR_doit(tf) \
if (!str) \
return _T("NULL"); \
\
LPTSTR c = getcyclestr(); \
_sntprintf(c, g_cyclelen, _T("\"") tf _T("\""), str); \
cap(c); \
return c;
LPCTSTR QSAFESTR(LPCWSTR str)
{
QSAFESTR_doit(_tfWSTR)
}
LPCTSTR QSAFESTR(LPCSTR str)
{
QSAFESTR_doit(_tfSTR)
}
LPCTSTR BOOLSTR(BOOL b)
{
return b ? _T("TRUE"): _T("FALSE");
}
LPCTSTR RECTSTR(RECT &rect)
{
LPTSTR c = getcyclestr();
_sntprintf(c, g_cyclelen, _T("{%d,%d,%d,%d}"),
rect.left,
rect.top,
rect.right,
rect.bottom);
cap(c);
return c;
}
LPCTSTR RECTDIMSTR(RECT &rect)
{
LPTSTR c = getcyclestr();
_sntprintf(c, g_cyclelen, _T("{%dx%d}"),
rect.right - rect.left,
rect.bottom - rect.top);
cap(c);
return c;
}
LPCTSTR POINTSTR(POINT &point)
{
LPTSTR c = getcyclestr();
_sntprintf(c, g_cyclelen, _T("{%d,%d}"),
point.x,
point.y);
cap(c);
return c;
}
LPCTSTR GUIDSTR(const GUID &guid)
{
LPTSTR c = getcyclestr();
wsprintf(c, _T("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1],
guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5],
guid.Data4[6], guid.Data4[7]);
cap(c);
return c;
}
template<class T>
static LPCTSTR _superstr(const T *str)
{
static LPCTSTR
prefix = _T("(\""),
midfix = _T("\",\""),
suffix = _T("\")");
LPTSTR c = getcyclestr(), c2 = getcyclestr();
c[0] = 0;
for (int i = 0, n = CountSubStrings(str); i < n; i++)
{
if (!i)
_tcsncat(c, prefix, g_cyclelen);
else
_tcsncat(c, midfix, g_cyclelen);
CopyStr(c2, GetSubString(str, i), g_cyclelen);
cap(c2);
_tcsncat(c, c2, g_cyclelen);
cap(c);
if (i == n - 1)
_tcsncat(c, suffix, g_cyclelen);
}
cap(c);
return c;
}
LPCTSTR SUPERSTR(LPCWSTR str) {return _superstr(str);}
LPCTSTR SUPERSTR(LPCSTR str) {return _superstr(str);}

View File

@@ -0,0 +1,31 @@
//-----------------------------------------------------------------------------
// File: cyclestr.h
//
// Desc: Implements a circular queue that provides space to hold a string
// without repeatedly allocating and deallocating memory. This is
// only for short-term use such as outputting debug message to
// ensure that the same buffer is not used at more than one place
// simultaneously.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __CYCLESTR_H__
#define __CYCLESTR_H__
LPTSTR getcyclestr();
LPCTSTR SAFESTR(LPCWSTR);
LPCTSTR SAFESTR(LPCSTR);
LPCTSTR QSAFESTR(LPCWSTR);
LPCTSTR QSAFESTR(LPCSTR);
LPCTSTR BOOLSTR(BOOL);
LPCTSTR RECTSTR(RECT &);
LPCTSTR RECTDIMSTR(RECT &);
LPCTSTR POINTSTR(POINT &);
LPCTSTR GUIDSTR(const GUID &);
LPCTSTR SUPERSTR(LPCWSTR);
LPCTSTR SUPERSTR(LPCSTR);
#endif //__CYCLESTR_H__

View File

@@ -0,0 +1,139 @@
//Microsoft Developer Studio generated resource script.
//
#include "dicfgres.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"dicfgres.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_AXESGLYPH BITMAP DISCARDABLE "axesglyph.bmp"
IDB_BUTTONGLYPH BITMAP DISCARDABLE "buttonglyph.bmp"
IDB_CHECKGLYPH BITMAP DISCARDABLE "checkglyph.bmp"
IDB_HATGLYPH BITMAP DISCARDABLE "hatglyph.bmp"
IDB_IB BITMAP DISCARDABLE "ib.bmp"
IDB_IB2 BITMAP DISCARDABLE "ib2.bmp"
IDB_CHECKGLYPHDARK BITMAP DISCARDABLE "bitmap1.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_DCONFIG_PRODUCTNAME "Device Action Configuration"
IDS_BUTTON_OK "OK"
IDS_TITLE_NOLOADVIEWIMAGE "Failed to Load Image"
IDS_NULLPATH "The path was NULL."
IDS_COULDNOTCREATEIMAGEFROMFILE "Could not create image from file ""%s""."
IDS_BUTTON_CANCEL "Cancel"
IDS_BUTTON_RESET "Reset"
IDS_INFOMSG_VIEW_TAB "Click to select a different device."
IDS_INFOMSG_VIEW_TABSCROLL "Click to scroll device tabs."
IDS_INFOMSG_VIEW_DEVICE "The current settings for this device are displayed to the right."
IDS_INFOMSG_VIEW_SORTDISABLED
"Click to show assigned actions at the top of the list."
IDS_INFOMSG_VIEW_SORTENABLED "Click to disable list sorting."
IDS_INFOMSG_VIEW_VIEWSEL "Click to see another view of this device."
IDS_INFOMSG_VIEW_OK "Click to close this window."
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_INFOMSG_VIEW_USERNAME "Displays the current user for this device."
IDS_INFOMSG_VIEW_GAMEMODE "Show settings for another mode."
IDS_INFOMSG_EDIT_TAB "Click to select a different device."
IDS_INFOMSG_EDIT_TABSCROLL "Click to scroll device tabs."
IDS_INFOMSG_EDIT_DEVICE "Select a control with the mouse, by moving an axis or by pressing a button."
IDS_INFOMSG_EDIT_SORTDISABLED
"Click to show assigned actions at the top of the list."
IDS_INFOMSG_EDIT_SORTENABLED "Click to disable list sorting."
IDS_INFOMSG_EDIT_VIEWSEL "Click to see another view of this device."
IDS_INFOMSG_EDIT_RESET "Click to return to the recommended settings for this device."
IDS_INFOMSG_EDIT_OK "Click to accept changes and close this dialog."
IDS_INFOMSG_EDIT_CANCEL "Click to cancel changes."
IDS_INFOMSG_EDIT_ACTLISTDISABLED
"Select a control on the device to be configured."
IDS_INFOMSG_EDIT_ACTLISTENABLED
"Press the Enter key, or double click the control to begin configuring it."
IDS_INFOMSG_EDIT_USERNAME "Assign this device to a player."
IDS_INFOMSG_EDIT_GAMEMODE "Configure for a different mode."
IDS_INFOMSG_DEF_EDIT "Select a control with the mouse, by moving an axis or by pressing a button."
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_INFOMSG_DEF_VIEW "The current settings for this device are displayed to the right."
IDS_INFOMSG_EDIT_CTRLSELECTED
"Edit the action assigned to this control by pressing ENTER or double clicking the control."
IDS_INFOMSG_EDIT_EDITMODEENABLED
"Choose an action for this control from the list. Press [Delete] to remove an action from the device. Press [Escape] to stop changes."
IDS_INFOMSG_EDIT_KEYBOARD
"Select a control with the mouse or by pressing a key."
IDS_INFOMSG_EDIT_MOUSE "Select a control with the mouse."
IDS_INFOMSG_APPFIXEDSELECT "This control cannot be remapped."
IDS_INFO_TITLE "Information"
IDS_PLAYER_TITLE "Player"
IDS_GENRE_TITLE "Game Mode"
IDS_AVAILABLEACTIONS_TITLE "Available Actions"
IDS_SORTASSIGNED "Sort Assigned"
IDS_AXISACTIONS "Axis Actions"
IDS_BUTTONACTIONS "Button Actions"
IDS_POVACTIONS "POV Actions"
IDS_LISTHEADER_CTRL "Controls"
IDS_LISTHEADER_ACTION "Actions"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_RESETMSG "Resetting the device..."
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,64 @@
//-----------------------------------------------------------------------------
// File: defines.h
//
// Desc: Contains all defined symbols needed for the UI.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __CFGUI_DEFINES_H__
#define __CFGUI_DEFINES_H__
// if either UNICODE define exists, make sure both do
#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE
#endif
#endif
#ifdef _UNICODE
#ifndef UNICODE
#define UNICODE
#endif
#endif
// make sure we have the correct debug flags defined,
// thus making sure assert actually works with build
#if defined(DBG) || defined(DEBUG)
#ifdef NDEBUG
#undef NDEBUG
#endif
#else
#ifndef NDEBUG
#define NDEBUG
#endif
#endif
// disable tracing if we don't want debug info
#ifdef NDEBUG
#ifndef NTRACE
#define NTRACE
#endif
#ifndef NO_LTRACE
#define NO_LTRACE
#endif
#endif
// settings...
//#define CFGUI__FORCE_GOOD_ACFORS
//#define CFGUI__FORCE_NON_NULL_WSZUSERNAMES
//#define CFGUI__TRACE_ACTION_FORMATS
//#define CFGUI__ALLOW_USER_ACTION_TREE_BRANCH_MANIPULATION
#define CFGUI__UIGLOBALS_HAS_CURUSER
#define CFGUI__COMPAREACTIONNAMES_CASE_INSENSITIVE
//#define __CFGUI_TRACE__TO_DEBUG_OUT
#define __CFGUI_TRACE__TO_FILE
#endif //__CFGUI_DEFINES_H__

View File

@@ -0,0 +1,7 @@
LIBRARY diconfig.dll
EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE

View File

@@ -0,0 +1,101 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by dconfig.rc
//
#define IDS_MSGBOXTITLE_WRITEINISUCCEEDED 1
#define IDS_MSGBOXTITLE_WRITEINIFAILED 2
#define IDS_WROTEINITO 3
#define IDS_DICREATEFAILED 4
#define IDS_CREATEDEVICEFAILED 5
#define IDS_GETPROPMAPFILEFAILED 6
#define IDS_WCTOMBFAILED 7
#define IDS_NOMAPFILEPATH 8
#define IDS_ERRORUNKNOWN 9
#define IDS_REMOVEALLCALLOUTS 10
#define IDS_CONFIRMREMOVEALLCALLOUTS 11
#define IDS_REMOVEVIEW 12
#define IDS_CONFIRMREMOVEVIEW 13
#define IDS_REMOVEALLVIEWS 14
#define IDS_CONFIRMREMOVEALLVIEWS 15
#define IDS_TITLE_NONEWCONTROL 16
#define IDS_ERROR_OFFSETUNAVAIL 17
#define IDS_GETPROPVIDPIDFAILED 18
#define IDS_ERROR_INIREAD 19
#define IDS_ERROR_CANTLOADDIMAP 20
#define IDS_ERROR_OUTOFMEMORY 21
#define IDS_BUTTON_LAYOUT 22
#define IDS_ERROR_WRITEVENDORFILE_FAILED 23
#define IDS_WRITEVENDORFILE_ACCESSDENIED 24
#define IDS_DCONFIG_PRODUCTNAME 25
#define IDS_BUTTON_OK 26
#define IDS_TITLE_NOLOADVIEWIMAGE 27
#define IDS_NULLPATH 28
#define IDS_COULDNOTCREATEIMAGEFROMFILE 29
#define IDS_BUTTON_CANCEL 30
#define IDS_BUTTON_RESET 31
#define IDS_INFOMSG_VIEW_TAB 32
#define IDS_INFOMSG_VIEW_TABSCROLL 33
#define IDS_INFOMSG_VIEW_DEVICE 34
#define IDS_INFOMSG_VIEW_SORTDISABLED 35
#define IDS_INFOMSG_VIEW_SORTENABLED 36
#define IDS_INFOMSG_VIEW_VIEWSEL 37
#define IDS_INFOMSG_VIEW_OK 38
#define IDS_INFOMSG_VIEW_USERNAME 39
#define IDS_INFOMSG_VIEW_GAMEMODE 40
#define IDS_INFOMSG_EDIT_TAB 41
#define IDS_INFOMSG_EDIT_TABSCROLL 42
#define IDS_INFOMSG_EDIT_DEVICE 43
#define IDS_INFOMSG_EDIT_SORTDISABLED 44
#define IDS_INFOMSG_EDIT_SORTENABLED 45
#define IDS_INFOMSG_EDIT_VIEWSEL 46
#define IDS_INFOMSG_EDIT_RESET 47
#define IDS_INFOMSG_EDIT_OK 48
#define IDS_INFOMSG_EDIT_CANCEL 49
#define IDS_INFOMSG_EDIT_ACTLISTDISABLED 50
#define IDS_INFOMSG_EDIT_ACTLISTENABLED 51
#define IDS_INFOMSG_EDIT_USERNAME 52
#define IDS_INFOMSG_EDIT_GAMEMODE 53
#define IDS_INFOMSG_DEF_EDIT 54
#define IDS_INFOMSG_DEF_VIEW 55
#define IDS_INFOMSG_EDIT_CTRLSELECTED 56
#define IDS_INFOMSG_EDIT_EDITMODEENABLED 57
#define IDS_INFOMSG_EDIT_KEYBOARD 58
#define IDS_INFOMSG_EDIT_MOUSE 59
#define IDS_INFOMSG_APPFIXEDSELECT 60
#define IDS_INFO_TITLE 61
#define IDS_PLAYER_TITLE 62
#define IDS_GENRE_TITLE 63
#define IDS_AVAILABLEACTIONS_TITLE 64
#define IDS_SORTASSIGNED 65
#define IDS_AXISACTIONS 66
#define IDS_BUTTONACTIONS 67
#define IDS_POVACTIONS 68
#define IDS_LISTHEADER_CTRL 69
#define IDS_LISTHEADER_ACTION 70
#define IDS_RESETMSG 71
#define IDD_DIACPAGE 102
#define IDD_SELCONTROLDLG 103
#define IDD_DCONFIG_DIALOG 104
#define IDB_IB 105
#define IDB_IB2 106
#define IDB_HATGLYPH 107
#define IDB_BUTTONGLYPH 108
#define IDB_CHECKGLYPH 109
#define IDB_AXESGLYPH 110
#define IDB_CHECKGLYPHDARK 111
#define IDC_TAB 1001
#define IDC_DEFAULT 1002
#define IDC_LIST 1003
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 111
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1004
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,473 @@
# Microsoft Developer Studio Project File - Name="diconfig" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=diconfig - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "diconfig.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "diconfig.mak" CFG="diconfig - Win32 Debug Unicode"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "diconfig - Win32 Debug Unicode" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "diconfig - Win32 Release Unicode" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "diconfig - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "diconfig - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "diconfig - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DICONFIG_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GR /O2 /I "$(dxsdkroot)\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DICONFIG_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib ole32.lib uuid.lib dinput8.lib ddraw.lib d3d8.lib d3dx8.lib /nologo /dll /machine:I386 /libpath:"$(dxsdkroot)\lib" /stack:0x200000,0x200000
!ELSEIF "$(CFG)" == "diconfig - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Win32_Debug"
# PROP BASE Intermediate_Dir "Win32_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DICONFIG_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MTd /W3 /Gm /GR /Zi /Od /I "$(dxsdkroot)\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DICONFIG_EXPORTS" /D "DEBUG" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib ole32.lib uuid.lib dinput8.lib ddraw.lib d3d8.lib d3dx8.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"$(dxsdkroot)\lib" /stack:0x200000,0x200000
!ELSEIF "$(CFG)" == "diconfig - Win32 Debug Unicode"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Win32_Debug_Unicode"
# PROP BASE Intermediate_Dir "Win32_Debug_Unicode"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Win32_Debug_Unicode"
# PROP Intermediate_Dir "Win32_Debug_Unicode"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GR /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DICONFIG_EXPORTS" /D "DEBUG" /YX /FD /c
# ADD CPP /nologo /MTd /W3 /Gm /GR /Zi /Od /I "$(dxsdkroot)\include" /D "_MBCS" /D "_USRDLL" /D "DICONFIG_EXPORTS" /D "DEBUG" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "UNICODE" /D "_UNICODE" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib ole32.lib uuid.lib dinput8.lib ddraw.lib d3d8.lib d3dx8.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib ole32.lib uuid.lib dinput8.lib ddraw.lib d3d8.lib d3dx8.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"$(dxsdkroot)\lib" /stack:0x200000,0x200000
!ELSEIF "$(CFG)" == "diconfig - Win32 Release Unicode"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Win32_Release_Unicode"
# PROP BASE Intermediate_Dir "Win32_Release_Unicode"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Win32_Release_Unicode"
# PROP Intermediate_Dir "Win32_Release_Unicode"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GR /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DICONFIG_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GR /O2 /I "$(dxsdkroot)\include" /D "_MBCS" /D "_USRDLL" /D "DICONFIG_EXPORTS" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "UNICODE" /D "_UNICODE" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib ole32.lib uuid.lib dinput8.lib ddraw.lib d3d8.lib d3dx8.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib ole32.lib uuid.lib dinput8.lib ddraw.lib d3d8.lib d3dx8.lib /nologo /dll /machine:I386 /libpath:"$(dxsdkroot)\lib" /stack:0x200000,0x200000
!ENDIF
# Begin Target
# Name "diconfig - Win32 Release"
# Name "diconfig - Win32 Debug"
# Name "diconfig - Win32 Debug Unicode"
# Name "diconfig - Win32 Release Unicode"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\cbitmap.cpp
# End Source File
# Begin Source File
SOURCE=.\cd3dsurf.cpp
# End Source File
# Begin Source File
SOURCE=.\cdevicecontrol.cpp
# End Source File
# Begin Source File
SOURCE=.\cdeviceui.cpp
# End Source File
# Begin Source File
SOURCE=.\cdeviceview.cpp
# End Source File
# Begin Source File
SOURCE=.\cdeviceviewtext.cpp
# End Source File
# Begin Source File
SOURCE=.\cdiacpage.cpp
# End Source File
# Begin Source File
SOURCE=.\cfguitrace.cpp
# End Source File
# Begin Source File
SOURCE=.\cfrmwrk.cpp
# End Source File
# Begin Source File
SOURCE=.\configwnd.cpp
# End Source File
# Begin Source File
SOURCE=.\constants.cpp
# End Source File
# Begin Source File
SOURCE=.\cyclestr.cpp
# End Source File
# Begin Source File
SOURCE=.\dconfig.rc
# End Source File
# Begin Source File
SOURCE=.\diactfrm.def
# End Source File
# Begin Source File
SOURCE=.\flexcheckbox.cpp
# End Source File
# Begin Source File
SOURCE=.\flexcombobox.cpp
# End Source File
# Begin Source File
SOURCE=.\flexinfobox.cpp
# End Source File
# Begin Source File
SOURCE=.\flexlistbox.cpp
# End Source File
# Begin Source File
SOURCE=.\flexmsgbox.cpp
# End Source File
# Begin Source File
SOURCE=.\flexscrollbar.cpp
# End Source File
# Begin Source File
SOURCE=.\flextooltip.cpp
# End Source File
# Begin Source File
SOURCE=.\flextree.cpp
# End Source File
# Begin Source File
SOURCE=.\flexwnd.cpp
# End Source File
# Begin Source File
SOURCE=.\guids.c
# End Source File
# Begin Source File
SOURCE=.\iclassfact.cpp
# End Source File
# Begin Source File
SOURCE=.\ipageclassfact.cpp
# End Source File
# Begin Source File
SOURCE=.\main.cpp
# End Source File
# Begin Source File
SOURCE=.\populate.cpp
# End Source File
# Begin Source File
SOURCE=.\privcom.cpp
# End Source File
# Begin Source File
SOURCE=.\registry.cpp
# End Source File
# Begin Source File
SOURCE=.\selcontroldlg.cpp
# End Source File
# Begin Source File
SOURCE=.\uiglobals.cpp
# End Source File
# Begin Source File
SOURCE=.\usefuldi.cpp
# End Source File
# Begin Source File
SOURCE=.\viewselwnd.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\bidirlookup.h
# End Source File
# Begin Source File
SOURCE=.\cbitmap.h
# End Source File
# Begin Source File
SOURCE=.\cdevicecontrol.h
# End Source File
# Begin Source File
SOURCE=.\cdeviceui.h
# End Source File
# Begin Source File
SOURCE=.\cdeviceview.h
# End Source File
# Begin Source File
SOURCE=.\cdeviceviewtext.h
# End Source File
# Begin Source File
SOURCE=.\cdiacpage.h
# End Source File
# Begin Source File
SOURCE=.\cfguitrace.h
# End Source File
# Begin Source File
SOURCE=.\cfrmwrk.h
# End Source File
# Begin Source File
SOURCE=.\collections.h
# End Source File
# Begin Source File
SOURCE=.\configwnd.h
# End Source File
# Begin Source File
SOURCE=.\constants.h
# End Source File
# Begin Source File
SOURCE=.\cyclestr.h
# End Source File
# Begin Source File
SOURCE=.\defines.h
# End Source File
# Begin Source File
SOURCE=.\dicfgres.h
# End Source File
# Begin Source File
SOURCE=.\flexcheckbox.h
# End Source File
# Begin Source File
SOURCE=.\flexcombobox.h
# End Source File
# Begin Source File
SOURCE=.\flexinfobox.h
# End Source File
# Begin Source File
SOURCE=.\flexlistbox.h
# End Source File
# Begin Source File
SOURCE=.\flexmsg.h
# End Source File
# Begin Source File
SOURCE=.\flexmsgbox.h
# End Source File
# Begin Source File
SOURCE=.\flexscrollbar.h
# End Source File
# Begin Source File
SOURCE=.\flextooltip.h
# End Source File
# Begin Source File
SOURCE=.\flextree.h
# End Source File
# Begin Source File
SOURCE=.\flexwnd.h
# End Source File
# Begin Source File
SOURCE=.\iclassfact.h
# End Source File
# Begin Source File
SOURCE=.\id3dsurf.h
# End Source File
# Begin Source File
SOURCE=.\idiacpage.h
# End Source File
# Begin Source File
SOURCE=.\ifrmwrk.h
# End Source File
# Begin Source File
SOURCE=.\ipageclassfact.h
# End Source File
# Begin Source File
SOURCE=.\iuiframe.h
# End Source File
# Begin Source File
SOURCE=.\ltrace.h
# End Source File
# Begin Source File
SOURCE=.\main.h
# End Source File
# Begin Source File
SOURCE=.\ourguids.h
# End Source File
# Begin Source File
SOURCE=.\pagecommon.h
# End Source File
# Begin Source File
SOURCE=.\populate.h
# End Source File
# Begin Source File
SOURCE=.\privcom.h
# End Source File
# Begin Source File
SOURCE=.\registry.h
# End Source File
# Begin Source File
SOURCE=.\selcontroldlg.h
# End Source File
# Begin Source File
SOURCE=.\uielements.h
# End Source File
# Begin Source File
SOURCE=.\uiglobals.h
# End Source File
# Begin Source File
SOURCE=.\useful.h
# End Source File
# Begin Source File
SOURCE=.\usefuldi.h
# End Source File
# Begin Source File
SOURCE=.\viewselwnd.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "diconfig"=.\diconfig.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -0,0 +1,769 @@
# Microsoft Developer Studio Generated NMAKE File, Based on diconfig.dsp
!IF "$(CFG)" == ""
CFG=diconfig - Win32 Debug Unicode
!MESSAGE No configuration specified. Defaulting to diconfig - Win32 Debug Unicode.
!ENDIF
!IF "$(CFG)" != "diconfig - Win32 Release" && "$(CFG)" != "diconfig - Win32 Debug" && "$(CFG)" != "diconfig - Win32 Debug Unicode" && "$(CFG)" != "diconfig - Win32 Release Unicode"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "diconfig.mak" CFG="diconfig - Win32 Debug Unicode"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "diconfig - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "diconfig - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "diconfig - Win32 Debug Unicode" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "diconfig - Win32 Release Unicode" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE
NULL=nul
!ENDIF
!IF "$(CFG)" == "diconfig - Win32 Release"
OUTDIR=.\Release
INTDIR=.\Release
# Begin Custom Macros
OutDir=.\Release
# End Custom Macros
ALL : "$(OUTDIR)\diconfig.dll"
CLEAN :
-@erase "$(INTDIR)\cbitmap.obj"
-@erase "$(INTDIR)\cd3dsurf.obj"
-@erase "$(INTDIR)\cdevicecontrol.obj"
-@erase "$(INTDIR)\cdeviceui.obj"
-@erase "$(INTDIR)\cdeviceview.obj"
-@erase "$(INTDIR)\cdeviceviewtext.obj"
-@erase "$(INTDIR)\cdiacpage.obj"
-@erase "$(INTDIR)\cfguitrace.obj"
-@erase "$(INTDIR)\cfrmwrk.obj"
-@erase "$(INTDIR)\configwnd.obj"
-@erase "$(INTDIR)\constants.obj"
-@erase "$(INTDIR)\cyclestr.obj"
-@erase "$(INTDIR)\dconfig.res"
-@erase "$(INTDIR)\flexcheckbox.obj"
-@erase "$(INTDIR)\flexcombobox.obj"
-@erase "$(INTDIR)\flexinfobox.obj"
-@erase "$(INTDIR)\flexlistbox.obj"
-@erase "$(INTDIR)\flexmsgbox.obj"
-@erase "$(INTDIR)\flexscrollbar.obj"
-@erase "$(INTDIR)\flextooltip.obj"
-@erase "$(INTDIR)\flextree.obj"
-@erase "$(INTDIR)\flexwnd.obj"
-@erase "$(INTDIR)\guids.obj"
-@erase "$(INTDIR)\iclassfact.obj"
-@erase "$(INTDIR)\ipageclassfact.obj"
-@erase "$(INTDIR)\main.obj"
-@erase "$(INTDIR)\populate.obj"
-@erase "$(INTDIR)\privcom.obj"
-@erase "$(INTDIR)\registry.obj"
-@erase "$(INTDIR)\selcontroldlg.obj"
-@erase "$(INTDIR)\uiglobals.obj"
-@erase "$(INTDIR)\usefuldi.obj"
-@erase "$(INTDIR)\vc60.idb"
-@erase "$(INTDIR)\viewselwnd.obj"
-@erase "$(OUTDIR)\diconfig.dll"
-@erase "$(OUTDIR)\diconfig.exp"
-@erase "$(OUTDIR)\diconfig.lib"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP=cl.exe
CPP_PROJ=/nologo /MT /W3 /GR /O2 /I "$(dxsdkroot)\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DICONFIG_EXPORTS" /Fp"$(INTDIR)\diconfig.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.c{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
MTL=midl.exe
MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
RSC=rc.exe
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\dconfig.res" /d "NDEBUG"
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\diconfig.bsc"
BSC32_SBRS= \
LINK32=link.exe
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib ole32.lib uuid.lib dinput8.lib ddraw.lib d3d8.lib d3dx8.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\diconfig.pdb" /machine:I386 /def:".\diactfrm.def" /out:"$(OUTDIR)\diconfig.dll" /implib:"$(OUTDIR)\diconfig.lib" /libpath:"$(dxsdkroot)\lib" /stack:0x200000,0x200000
DEF_FILE= \
".\diactfrm.def"
LINK32_OBJS= \
"$(INTDIR)\cbitmap.obj" \
"$(INTDIR)\cd3dsurf.obj" \
"$(INTDIR)\cdevicecontrol.obj" \
"$(INTDIR)\cdeviceui.obj" \
"$(INTDIR)\cdeviceview.obj" \
"$(INTDIR)\cdeviceviewtext.obj" \
"$(INTDIR)\cdiacpage.obj" \
"$(INTDIR)\cfguitrace.obj" \
"$(INTDIR)\cfrmwrk.obj" \
"$(INTDIR)\configwnd.obj" \
"$(INTDIR)\constants.obj" \
"$(INTDIR)\cyclestr.obj" \
"$(INTDIR)\flexcheckbox.obj" \
"$(INTDIR)\flexcombobox.obj" \
"$(INTDIR)\flexinfobox.obj" \
"$(INTDIR)\flexlistbox.obj" \
"$(INTDIR)\flexmsgbox.obj" \
"$(INTDIR)\flexscrollbar.obj" \
"$(INTDIR)\flextooltip.obj" \
"$(INTDIR)\flextree.obj" \
"$(INTDIR)\flexwnd.obj" \
"$(INTDIR)\guids.obj" \
"$(INTDIR)\iclassfact.obj" \
"$(INTDIR)\ipageclassfact.obj" \
"$(INTDIR)\main.obj" \
"$(INTDIR)\populate.obj" \
"$(INTDIR)\privcom.obj" \
"$(INTDIR)\registry.obj" \
"$(INTDIR)\selcontroldlg.obj" \
"$(INTDIR)\uiglobals.obj" \
"$(INTDIR)\usefuldi.obj" \
"$(INTDIR)\viewselwnd.obj" \
"$(INTDIR)\dconfig.res"
"$(OUTDIR)\diconfig.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "diconfig - Win32 Debug"
OUTDIR=.\Debug
INTDIR=.\Debug
# Begin Custom Macros
OutDir=.\Debug
# End Custom Macros
ALL : "$(OUTDIR)\diconfig.dll"
CLEAN :
-@erase "$(INTDIR)\cbitmap.obj"
-@erase "$(INTDIR)\cd3dsurf.obj"
-@erase "$(INTDIR)\cdevicecontrol.obj"
-@erase "$(INTDIR)\cdeviceui.obj"
-@erase "$(INTDIR)\cdeviceview.obj"
-@erase "$(INTDIR)\cdeviceviewtext.obj"
-@erase "$(INTDIR)\cdiacpage.obj"
-@erase "$(INTDIR)\cfguitrace.obj"
-@erase "$(INTDIR)\cfrmwrk.obj"
-@erase "$(INTDIR)\configwnd.obj"
-@erase "$(INTDIR)\constants.obj"
-@erase "$(INTDIR)\cyclestr.obj"
-@erase "$(INTDIR)\dconfig.res"
-@erase "$(INTDIR)\flexcheckbox.obj"
-@erase "$(INTDIR)\flexcombobox.obj"
-@erase "$(INTDIR)\flexinfobox.obj"
-@erase "$(INTDIR)\flexlistbox.obj"
-@erase "$(INTDIR)\flexmsgbox.obj"
-@erase "$(INTDIR)\flexscrollbar.obj"
-@erase "$(INTDIR)\flextooltip.obj"
-@erase "$(INTDIR)\flextree.obj"
-@erase "$(INTDIR)\flexwnd.obj"
-@erase "$(INTDIR)\guids.obj"
-@erase "$(INTDIR)\iclassfact.obj"
-@erase "$(INTDIR)\ipageclassfact.obj"
-@erase "$(INTDIR)\main.obj"
-@erase "$(INTDIR)\populate.obj"
-@erase "$(INTDIR)\privcom.obj"
-@erase "$(INTDIR)\registry.obj"
-@erase "$(INTDIR)\selcontroldlg.obj"
-@erase "$(INTDIR)\uiglobals.obj"
-@erase "$(INTDIR)\usefuldi.obj"
-@erase "$(INTDIR)\vc60.idb"
-@erase "$(INTDIR)\vc60.pdb"
-@erase "$(INTDIR)\viewselwnd.obj"
-@erase "$(OUTDIR)\diconfig.dll"
-@erase "$(OUTDIR)\diconfig.exp"
-@erase "$(OUTDIR)\diconfig.ilk"
-@erase "$(OUTDIR)\diconfig.lib"
-@erase "$(OUTDIR)\diconfig.pdb"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP=cl.exe
CPP_PROJ=/nologo /MTd /W3 /Gm /GR /Zi /Od /I "$(dxsdkroot)\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DICONFIG_EXPORTS" /D "DEBUG" /Fp"$(INTDIR)\diconfig.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.c{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
MTL=midl.exe
MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
RSC=rc.exe
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\dconfig.res" /d "_DEBUG"
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\diconfig.bsc"
BSC32_SBRS= \
LINK32=link.exe
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib ole32.lib uuid.lib dinput8.lib ddraw.lib d3d8.lib d3dx8.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\diconfig.pdb" /debug /machine:I386 /def:".\diactfrm.def" /out:"$(OUTDIR)\diconfig.dll" /implib:"$(OUTDIR)\diconfig.lib" /pdbtype:sept /libpath:"$(dxsdkroot)\lib" /stack:0x200000,0x200000
DEF_FILE= \
".\diactfrm.def"
LINK32_OBJS= \
"$(INTDIR)\cbitmap.obj" \
"$(INTDIR)\cd3dsurf.obj" \
"$(INTDIR)\cdevicecontrol.obj" \
"$(INTDIR)\cdeviceui.obj" \
"$(INTDIR)\cdeviceview.obj" \
"$(INTDIR)\cdeviceviewtext.obj" \
"$(INTDIR)\cdiacpage.obj" \
"$(INTDIR)\cfguitrace.obj" \
"$(INTDIR)\cfrmwrk.obj" \
"$(INTDIR)\configwnd.obj" \
"$(INTDIR)\constants.obj" \
"$(INTDIR)\cyclestr.obj" \
"$(INTDIR)\flexcheckbox.obj" \
"$(INTDIR)\flexcombobox.obj" \
"$(INTDIR)\flexinfobox.obj" \
"$(INTDIR)\flexlistbox.obj" \
"$(INTDIR)\flexmsgbox.obj" \
"$(INTDIR)\flexscrollbar.obj" \
"$(INTDIR)\flextooltip.obj" \
"$(INTDIR)\flextree.obj" \
"$(INTDIR)\flexwnd.obj" \
"$(INTDIR)\guids.obj" \
"$(INTDIR)\iclassfact.obj" \
"$(INTDIR)\ipageclassfact.obj" \
"$(INTDIR)\main.obj" \
"$(INTDIR)\populate.obj" \
"$(INTDIR)\privcom.obj" \
"$(INTDIR)\registry.obj" \
"$(INTDIR)\selcontroldlg.obj" \
"$(INTDIR)\uiglobals.obj" \
"$(INTDIR)\usefuldi.obj" \
"$(INTDIR)\viewselwnd.obj" \
"$(INTDIR)\dconfig.res"
"$(OUTDIR)\diconfig.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "diconfig - Win32 Debug Unicode"
OUTDIR=.\Win32_Debug_Unicode
INTDIR=.\Win32_Debug_Unicode
# Begin Custom Macros
OutDir=.\Win32_Debug_Unicode
# End Custom Macros
ALL : "$(OUTDIR)\diconfig.dll"
CLEAN :
-@erase "$(INTDIR)\cbitmap.obj"
-@erase "$(INTDIR)\cd3dsurf.obj"
-@erase "$(INTDIR)\cdevicecontrol.obj"
-@erase "$(INTDIR)\cdeviceui.obj"
-@erase "$(INTDIR)\cdeviceview.obj"
-@erase "$(INTDIR)\cdeviceviewtext.obj"
-@erase "$(INTDIR)\cdiacpage.obj"
-@erase "$(INTDIR)\cfguitrace.obj"
-@erase "$(INTDIR)\cfrmwrk.obj"
-@erase "$(INTDIR)\configwnd.obj"
-@erase "$(INTDIR)\constants.obj"
-@erase "$(INTDIR)\cyclestr.obj"
-@erase "$(INTDIR)\dconfig.res"
-@erase "$(INTDIR)\flexcheckbox.obj"
-@erase "$(INTDIR)\flexcombobox.obj"
-@erase "$(INTDIR)\flexinfobox.obj"
-@erase "$(INTDIR)\flexlistbox.obj"
-@erase "$(INTDIR)\flexmsgbox.obj"
-@erase "$(INTDIR)\flexscrollbar.obj"
-@erase "$(INTDIR)\flextooltip.obj"
-@erase "$(INTDIR)\flextree.obj"
-@erase "$(INTDIR)\flexwnd.obj"
-@erase "$(INTDIR)\guids.obj"
-@erase "$(INTDIR)\iclassfact.obj"
-@erase "$(INTDIR)\ipageclassfact.obj"
-@erase "$(INTDIR)\main.obj"
-@erase "$(INTDIR)\populate.obj"
-@erase "$(INTDIR)\privcom.obj"
-@erase "$(INTDIR)\registry.obj"
-@erase "$(INTDIR)\selcontroldlg.obj"
-@erase "$(INTDIR)\uiglobals.obj"
-@erase "$(INTDIR)\usefuldi.obj"
-@erase "$(INTDIR)\vc60.idb"
-@erase "$(INTDIR)\vc60.pdb"
-@erase "$(INTDIR)\viewselwnd.obj"
-@erase "$(OUTDIR)\diconfig.dll"
-@erase "$(OUTDIR)\diconfig.exp"
-@erase "$(OUTDIR)\diconfig.ilk"
-@erase "$(OUTDIR)\diconfig.lib"
-@erase "$(OUTDIR)\diconfig.pdb"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP=cl.exe
CPP_PROJ=/nologo /MTd /W3 /Gm /GR /Zi /Od /I "$(dxsdkroot)\include" /D "_MBCS" /D "_USRDLL" /D "DICONFIG_EXPORTS" /D "DEBUG" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "UNICODE" /D "_UNICODE" /Fp"$(INTDIR)\diconfig.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.c{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
MTL=midl.exe
MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
RSC=rc.exe
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\dconfig.res" /d "_DEBUG"
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\diconfig.bsc"
BSC32_SBRS= \
LINK32=link.exe
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib ole32.lib uuid.lib dinput8.lib ddraw.lib d3d8.lib d3dx8.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\diconfig.pdb" /debug /machine:I386 /def:".\diactfrm.def" /out:"$(OUTDIR)\diconfig.dll" /implib:"$(OUTDIR)\diconfig.lib" /pdbtype:sept /libpath:"$(dxsdkroot)\lib" /stack:0x200000,0x200000
DEF_FILE= \
".\diactfrm.def"
LINK32_OBJS= \
"$(INTDIR)\cbitmap.obj" \
"$(INTDIR)\cd3dsurf.obj" \
"$(INTDIR)\cdevicecontrol.obj" \
"$(INTDIR)\cdeviceui.obj" \
"$(INTDIR)\cdeviceview.obj" \
"$(INTDIR)\cdeviceviewtext.obj" \
"$(INTDIR)\cdiacpage.obj" \
"$(INTDIR)\cfguitrace.obj" \
"$(INTDIR)\cfrmwrk.obj" \
"$(INTDIR)\configwnd.obj" \
"$(INTDIR)\constants.obj" \
"$(INTDIR)\cyclestr.obj" \
"$(INTDIR)\flexcheckbox.obj" \
"$(INTDIR)\flexcombobox.obj" \
"$(INTDIR)\flexinfobox.obj" \
"$(INTDIR)\flexlistbox.obj" \
"$(INTDIR)\flexmsgbox.obj" \
"$(INTDIR)\flexscrollbar.obj" \
"$(INTDIR)\flextooltip.obj" \
"$(INTDIR)\flextree.obj" \
"$(INTDIR)\flexwnd.obj" \
"$(INTDIR)\guids.obj" \
"$(INTDIR)\iclassfact.obj" \
"$(INTDIR)\ipageclassfact.obj" \
"$(INTDIR)\main.obj" \
"$(INTDIR)\populate.obj" \
"$(INTDIR)\privcom.obj" \
"$(INTDIR)\registry.obj" \
"$(INTDIR)\selcontroldlg.obj" \
"$(INTDIR)\uiglobals.obj" \
"$(INTDIR)\usefuldi.obj" \
"$(INTDIR)\viewselwnd.obj" \
"$(INTDIR)\dconfig.res"
"$(OUTDIR)\diconfig.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "diconfig - Win32 Release Unicode"
OUTDIR=.\Win32_Release_Unicode
INTDIR=.\Win32_Release_Unicode
# Begin Custom Macros
OutDir=.\Win32_Release_Unicode
# End Custom Macros
ALL : "$(OUTDIR)\diconfig.dll"
CLEAN :
-@erase "$(INTDIR)\cbitmap.obj"
-@erase "$(INTDIR)\cd3dsurf.obj"
-@erase "$(INTDIR)\cdevicecontrol.obj"
-@erase "$(INTDIR)\cdeviceui.obj"
-@erase "$(INTDIR)\cdeviceview.obj"
-@erase "$(INTDIR)\cdeviceviewtext.obj"
-@erase "$(INTDIR)\cdiacpage.obj"
-@erase "$(INTDIR)\cfguitrace.obj"
-@erase "$(INTDIR)\cfrmwrk.obj"
-@erase "$(INTDIR)\configwnd.obj"
-@erase "$(INTDIR)\constants.obj"
-@erase "$(INTDIR)\cyclestr.obj"
-@erase "$(INTDIR)\dconfig.res"
-@erase "$(INTDIR)\flexcheckbox.obj"
-@erase "$(INTDIR)\flexcombobox.obj"
-@erase "$(INTDIR)\flexinfobox.obj"
-@erase "$(INTDIR)\flexlistbox.obj"
-@erase "$(INTDIR)\flexmsgbox.obj"
-@erase "$(INTDIR)\flexscrollbar.obj"
-@erase "$(INTDIR)\flextooltip.obj"
-@erase "$(INTDIR)\flextree.obj"
-@erase "$(INTDIR)\flexwnd.obj"
-@erase "$(INTDIR)\guids.obj"
-@erase "$(INTDIR)\iclassfact.obj"
-@erase "$(INTDIR)\ipageclassfact.obj"
-@erase "$(INTDIR)\main.obj"
-@erase "$(INTDIR)\populate.obj"
-@erase "$(INTDIR)\privcom.obj"
-@erase "$(INTDIR)\registry.obj"
-@erase "$(INTDIR)\selcontroldlg.obj"
-@erase "$(INTDIR)\uiglobals.obj"
-@erase "$(INTDIR)\usefuldi.obj"
-@erase "$(INTDIR)\vc60.idb"
-@erase "$(INTDIR)\viewselwnd.obj"
-@erase "$(OUTDIR)\diconfig.dll"
-@erase "$(OUTDIR)\diconfig.exp"
-@erase "$(OUTDIR)\diconfig.lib"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP=cl.exe
CPP_PROJ=/nologo /MT /W3 /GR /O2 /I "$(dxsdkroot)\include" /D "_MBCS" /D "_USRDLL" /D "DICONFIG_EXPORTS" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "UNICODE" /D "_UNICODE" /Fp"$(INTDIR)\diconfig.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.c{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
MTL=midl.exe
MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
RSC=rc.exe
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\dconfig.res" /d "NDEBUG"
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\diconfig.bsc"
BSC32_SBRS= \
LINK32=link.exe
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib ole32.lib uuid.lib dinput8.lib ddraw.lib d3d8.lib d3dx8.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\diconfig.pdb" /machine:I386 /def:".\diactfrm.def" /out:"$(OUTDIR)\diconfig.dll" /implib:"$(OUTDIR)\diconfig.lib" /libpath:"$(dxsdkroot)\lib" /stack:0x200000,0x200000
DEF_FILE= \
".\diactfrm.def"
LINK32_OBJS= \
"$(INTDIR)\cbitmap.obj" \
"$(INTDIR)\cd3dsurf.obj" \
"$(INTDIR)\cdevicecontrol.obj" \
"$(INTDIR)\cdeviceui.obj" \
"$(INTDIR)\cdeviceview.obj" \
"$(INTDIR)\cdeviceviewtext.obj" \
"$(INTDIR)\cdiacpage.obj" \
"$(INTDIR)\cfguitrace.obj" \
"$(INTDIR)\cfrmwrk.obj" \
"$(INTDIR)\configwnd.obj" \
"$(INTDIR)\constants.obj" \
"$(INTDIR)\cyclestr.obj" \
"$(INTDIR)\flexcheckbox.obj" \
"$(INTDIR)\flexcombobox.obj" \
"$(INTDIR)\flexinfobox.obj" \
"$(INTDIR)\flexlistbox.obj" \
"$(INTDIR)\flexmsgbox.obj" \
"$(INTDIR)\flexscrollbar.obj" \
"$(INTDIR)\flextooltip.obj" \
"$(INTDIR)\flextree.obj" \
"$(INTDIR)\flexwnd.obj" \
"$(INTDIR)\guids.obj" \
"$(INTDIR)\iclassfact.obj" \
"$(INTDIR)\ipageclassfact.obj" \
"$(INTDIR)\main.obj" \
"$(INTDIR)\populate.obj" \
"$(INTDIR)\privcom.obj" \
"$(INTDIR)\registry.obj" \
"$(INTDIR)\selcontroldlg.obj" \
"$(INTDIR)\uiglobals.obj" \
"$(INTDIR)\usefuldi.obj" \
"$(INTDIR)\viewselwnd.obj" \
"$(INTDIR)\dconfig.res"
"$(OUTDIR)\diconfig.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
!IF "$(NO_EXTERNAL_DEPS)" != "1"
!IF EXISTS("diconfig.dep")
!INCLUDE "diconfig.dep"
!ELSE
!MESSAGE Warning: cannot find "diconfig.dep"
!ENDIF
!ENDIF
!IF "$(CFG)" == "diconfig - Win32 Release" || "$(CFG)" == "diconfig - Win32 Debug" || "$(CFG)" == "diconfig - Win32 Debug Unicode" || "$(CFG)" == "diconfig - Win32 Release Unicode"
SOURCE=.\cbitmap.cpp
"$(INTDIR)\cbitmap.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\cd3dsurf.cpp
"$(INTDIR)\cd3dsurf.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\cdevicecontrol.cpp
"$(INTDIR)\cdevicecontrol.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\cdeviceui.cpp
"$(INTDIR)\cdeviceui.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\cdeviceview.cpp
"$(INTDIR)\cdeviceview.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\cdeviceviewtext.cpp
"$(INTDIR)\cdeviceviewtext.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\cdiacpage.cpp
"$(INTDIR)\cdiacpage.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\cfguitrace.cpp
"$(INTDIR)\cfguitrace.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\cfrmwrk.cpp
"$(INTDIR)\cfrmwrk.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\configwnd.cpp
"$(INTDIR)\configwnd.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\constants.cpp
"$(INTDIR)\constants.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\cyclestr.cpp
"$(INTDIR)\cyclestr.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\dconfig.rc
"$(INTDIR)\dconfig.res" : $(SOURCE) "$(INTDIR)"
$(RSC) $(RSC_PROJ) $(SOURCE)
SOURCE=.\flexcheckbox.cpp
"$(INTDIR)\flexcheckbox.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\flexcombobox.cpp
"$(INTDIR)\flexcombobox.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\flexinfobox.cpp
"$(INTDIR)\flexinfobox.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\flexlistbox.cpp
"$(INTDIR)\flexlistbox.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\flexmsgbox.cpp
"$(INTDIR)\flexmsgbox.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\flexscrollbar.cpp
"$(INTDIR)\flexscrollbar.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\flextooltip.cpp
"$(INTDIR)\flextooltip.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\flextree.cpp
"$(INTDIR)\flextree.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\flexwnd.cpp
"$(INTDIR)\flexwnd.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\guids.c
"$(INTDIR)\guids.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\iclassfact.cpp
"$(INTDIR)\iclassfact.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\ipageclassfact.cpp
"$(INTDIR)\ipageclassfact.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\main.cpp
"$(INTDIR)\main.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\populate.cpp
"$(INTDIR)\populate.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\privcom.cpp
"$(INTDIR)\privcom.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\registry.cpp
"$(INTDIR)\registry.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\selcontroldlg.cpp
"$(INTDIR)\selcontroldlg.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\uiglobals.cpp
"$(INTDIR)\uiglobals.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\usefuldi.cpp
"$(INTDIR)\usefuldi.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\viewselwnd.cpp
"$(INTDIR)\viewselwnd.obj" : $(SOURCE) "$(INTDIR)"
!ENDIF

View File

@@ -0,0 +1,224 @@
//-----------------------------------------------------------------------------
// File: flexcheckbox.cpp
//
// Desc: Implements a check box control similar to Windows check box.
// CFlexCheckBox is derived from CFlexWnd. The only place that
// uses CFlxCheckBox is in the keyboard for sorting by assigned
// keys.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
CFlexCheckBox::CFlexCheckBox() :
m_hWndNotify(NULL),
m_bChecked(FALSE),
m_rgbText(RGB(255,255,255)),
m_rgbBk(RGB(0,0,0)),
m_rgbSelText(RGB(0,0,255)),
m_rgbSelBk(RGB(0,0,0)),
m_rgbFill(RGB(0,0,255)),
m_rgbLine(RGB(0,255,255)),
m_hFont(NULL),
m_tszText(NULL)
{
}
CFlexCheckBox::~CFlexCheckBox()
{
delete[] m_tszText;
}
void CFlexCheckBox::SetText(LPCTSTR tszText)
{
LPTSTR tszTempText = NULL;
if (tszText)
{
tszTempText = new TCHAR[_tcslen(tszText) + 1];
if (!tszTempText) return;
_tcscpy(tszTempText, tszText);
}
delete[] m_tszText;
m_tszText = tszTempText;
}
void CFlexCheckBox::SetFont(HFONT hFont)
{
m_hFont = hFont;
if (m_hWnd == NULL)
return;
Invalidate();
}
void CFlexCheckBox::SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line)
{
m_rgbText = text;
m_rgbBk = bk;
m_rgbSelText = seltext;
m_rgbSelBk = selbk;
m_rgbFill = fill;
m_rgbLine = line;
Invalidate();
}
void CFlexCheckBox::SetRect()
{
if (m_hWnd == NULL)
return;
RECT rect = GetRect();
SetWindowPos(m_hWnd, NULL, rect.left, rect.top, rect.right, rect.bottom, SWP_NOZORDER | SWP_NOMOVE);
}
RECT CFlexCheckBox::GetRect(const RECT &rect)
{
int h = GetTextHeight(m_hFont);
RECT ret = {rect.left, rect.top, rect.right, rect.top + h + 2};
return ret;
}
RECT CFlexCheckBox::GetRect()
{
RECT rect;
GetClientRect(&rect);
return GetRect(rect);
}
void CFlexCheckBox::OnPaint(HDC hDC)
{
HDC hBDC = NULL, hODC = NULL;
CBitmap *pbm = NULL;
if (!InRenderMode())
{
hODC = hDC;
pbm = CBitmap::Create(GetClientSize(), RGB(0,0,0), hDC);
if (pbm != NULL)
{
hBDC = pbm->BeginPaintInto();
if (hBDC != NULL)
{
hDC = hBDC;
}
}
}
InternalPaint(hDC);
if (!InRenderMode())
{
if (pbm != NULL)
{
if (hBDC != NULL)
{
pbm->EndPaintInto(hBDC);
pbm->Draw(hODC);
}
delete pbm;
}
}
}
void CFlexCheckBox::InternalPaint(HDC hDC)
{
HGDIOBJ hBrush = (HGDIOBJ)CreateSolidBrush(m_rgbBk);
if (hBrush != NULL)
{
HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
// Erase the background first
RECT client;
GetClientRect(&client);
Rectangle(hDC, client.left, client.top, client.right, client.bottom);
// Create pen for check box
HGDIOBJ hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbLine);
if (hPen != NULL)
{
HGDIOBJ hOldPen = SelectObject(hDC, hPen);
RECT rect = {0, 0, 0, 0}, textrc;
GetClientRect(&rect);
textrc = rect;
int iBoxDim = rect.bottom - rect.top;
// Draw the square box
rect.right = rect.left + iBoxDim;
InflateRect(&rect, -2, -2);
OffsetRect(&rect, 0, -2); // Move up to align with the text
Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
// Draw the check mark if the state is checked.
if (m_bChecked)
{
HGDIOBJ hCrossPen = CreatePen(PS_SOLID, 3, m_rgbLine);
if (hCrossPen != NULL)
{
SelectObject(hDC, hCrossPen);
MoveToEx(hDC, rect.left + 2, rect.top + 2, NULL); // Upper left
LineTo(hDC, rect.right - 2, rect.bottom - 2); // Lower right
MoveToEx(hDC, rect.right - 2, rect.top + 2, NULL); // Upper right
LineTo(hDC, rect.left + 2, rect.bottom - 2); // Lower left
SelectObject(hDC, hPen);
DeleteObject(hCrossPen);
}
}
SetBkMode(hDC, TRANSPARENT);
// Draw the message text
SetTextColor(hDC, m_rgbText);
textrc.left = rect.right + 8;
DrawText(hDC, m_tszText, -1, &textrc, DT_LEFT|DT_NOPREFIX|DT_WORDBREAK);
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
}
SelectObject(hDC, hOldBrush);
DeleteObject(hBrush);
}
}
void CFlexCheckBox::Notify(int code)
{
if (!m_hWndNotify)
return;
PostMessage(m_hWndNotify, WM_FLEXCHECKBOX,
(WPARAM)code, (LPARAM)(LPVOID)this);
}
void CFlexCheckBox::OnClick(POINT point, WPARAM fwKeys, BOOL bLeft)
{
if (!m_hWnd)
return;
RECT rect;
GetClientRect(&rect);
rect.right = rect.left + (rect.bottom - rect.top); // Adjust the width to same as height.
InflateRect(&rect, -2, -2);
OffsetRect(&rect, 0, -2); // Move up to align with the text
if (PtInRect(&rect, point))
{
m_bChecked = !m_bChecked;
Invalidate();
Notify(m_bChecked ? CHKNOTIFY_CHECK : CHKNOTIFY_UNCHECK); // Notify the page object about the state change.
} else
{
// Unhighlight current callout
HWND hWndParent;
hWndParent = GetParent(m_hWnd);
SendMessage(hWndParent, WM_UNHIGHLIGHT, 0, 0); // Send click message to page to unhighlight callout
}
}
void CFlexCheckBox::OnMouseOver(POINT point, WPARAM fwKeys)
{
Notify(CHKNOTIFY_MOUSEOVER);
}

View File

@@ -0,0 +1,55 @@
//-----------------------------------------------------------------------------
// File: flexcheckbox.h
//
// Desc: Implements a check box control similar to Windows check box.
// CFlexCheckBox is derived from CFlexWnd. The only place that
// uses CFlxCheckBox is in the keyboard for sorting by assigned
// keys.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __FLEXCHECKBOX_H__
#define __FLEXCHECKBOX_H__
enum CHECKNOTIFY {
CHKNOTIFY_UNCHECK,
CHKNOTIFY_CHECK,
CHKNOTIFY_MOUSEOVER};
class CFlexCheckBox : public CFlexWnd
{
LPTSTR m_tszText; // Text string of the message
BOOL m_bChecked;
COLORREF m_rgbText, m_rgbBk, m_rgbSelText, m_rgbSelBk, m_rgbFill, m_rgbLine;
HFONT m_hFont;
HWND m_hWndNotify;
void SetRect();
void InternalPaint(HDC hDC);
RECT GetRect(const RECT &);
RECT GetRect();
void Notify(int code);
public:
CFlexCheckBox();
virtual ~CFlexCheckBox();
void SetNotify(HWND hWnd) { m_hWndNotify = hWnd; }
void SetCheck(BOOL bChecked) { m_bChecked = bChecked; }
BOOL GetCheck() { return m_bChecked; }
void SetText(LPCTSTR tszText);
// cosmetics
void SetFont(HFONT hFont);
void SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line);
virtual void OnPaint(HDC hDC);
virtual void OnClick(POINT point, WPARAM fwKeys, BOOL bLeft);
virtual void OnMouseOver(POINT point, WPARAM fwKeys);
};
#endif

View File

@@ -0,0 +1,476 @@
//-----------------------------------------------------------------------------
// File: flexcombobox.cpp
//
// Desc: Implements a combo box control similar to Windows combo box.
// CFlexComboBox is derived from CFlexWnd. It is used by the page
// for player list and genre list. When the combo box is open,
// CFlexComboBox uses a CFlexListBox for the list window.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
CFlexComboBox::CFlexComboBox() :
m_nTextHeight(-1),
m_hWndNotify(NULL),
m_rgbText(RGB(255,255,255)),
m_rgbBk(RGB(0,0,0)),
m_rgbSelText(RGB(0,0,255)),
m_rgbSelBk(RGB(0,0,0)),
m_rgbFill(RGB(0,0,255)),
m_rgbLine(RGB(0,255,255)),
m_dwFlags(0),
m_dwListBoxFlags(0),
m_bInSelMode(FALSE),
m_nSBWidth(11),
m_hFont(NULL),
m_eCurState(FCBS_CLOSED),
m_OldSel(-1)
{
}
CFlexComboBox::~CFlexComboBox()
{
}
CFlexComboBox *CreateFlexComboBox(FLEXCOMBOBOXCREATESTRUCT *pcs)
{
CFlexComboBox *psb = new CFlexComboBox;
if (psb && psb->Create(pcs))
return psb;
delete psb;
return NULL;
}
BOOL CFlexComboBox::Create(FLEXCOMBOBOXCREATESTRUCT *pcs)
{
if (this == NULL)
return FALSE;
if (pcs == NULL)
return FALSE;
if (pcs->dwSize != sizeof(FLEXCOMBOBOXCREATESTRUCT))
return FALSE;
m_hWndNotify = pcs->hWndNotify ? pcs->hWndNotify : pcs->hWndParent;
m_dwFlags = pcs->dwFlags;
m_dwListBoxFlags = pcs->dwListBoxFlags;
SetFont(pcs->hFont);
SetColors(pcs->rgbText, pcs->rgbBk, pcs->rgbSelText, pcs->rgbSelBk, pcs->rgbFill, pcs->rgbLine);
m_nSBWidth = pcs->nSBWidth;
m_rect = pcs->rect;
if (!CFlexWnd::Create(pcs->hWndParent, GetRect(pcs->rect), pcs->bVisible))
return FALSE;
return TRUE;
}
void CFlexComboBox::OnPaint(HDC hDC)
{
HDC hBDC = NULL, hODC = NULL;
CBitmap *pbm = NULL;
if (!InRenderMode())
{
hODC = hDC;
pbm = CBitmap::Create(GetClientSize(), RGB(0,0,0), hDC);
if (pbm != NULL)
{
hBDC = pbm->BeginPaintInto();
if (hBDC != NULL)
{
hDC = hBDC;
}
}
}
InternalPaint(hDC);
if (!InRenderMode())
{
if (pbm != NULL)
{
if (hBDC != NULL)
{
pbm->EndPaintInto(hBDC);
pbm->Draw(hODC);
}
delete pbm;
}
}
}
void CFlexComboBox::SetSel(int i)
{
m_ListBox.SelectAndShowSingleItem(i, TRUE);
}
int CFlexComboBox::GetSel()
{
return m_ListBox.GetSel();
}
LPCTSTR CFlexComboBox::GetText()
{
return m_ListBox.GetSelText();
}
void CFlexComboBox::InternalPaint(HDC hDC)
{
HGDIOBJ hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbLine);
if (hPen != NULL)
{
HGDIOBJ hOldPen = SelectObject(hDC, hPen);
HGDIOBJ hBrush = (HGDIOBJ)CreateSolidBrush(m_rgbBk);
if (hBrush != NULL)
{
HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
RECT rect = {0,0,0,0};
GetClientRect(&rect);
Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
RECT arect = rect;
arect.left = arect.right - (arect.bottom - arect.top);
// If we are read-only, only draw the text in gray. No border, no arrow.
if (!GetReadOnly())
{
MoveToEx(hDC, arect.left, arect.top, NULL);
LineTo(hDC, arect.left, arect.bottom);
}
rect.left++;
rect.top++;
rect.right = arect.left;
rect.bottom--;
SetTextColor(hDC, m_rgbText);
SetBkMode(hDC, TRANSPARENT);
LPTSTR lpText = (LPTSTR)GetText();
if (lpText)
{
DrawText(hDC, lpText, -1, &rect, DT_NOPREFIX);
}
SelectObject(hDC, hOldBrush);
DeleteObject(hBrush);
if (!GetReadOnly())
{
hBrush = (HGDIOBJ)CreateSolidBrush(m_rgbFill);
if (hBrush != NULL)
{
SelectObject(hDC, hBrush);
InflateRect(&arect, -3, -3);
DrawArrow(hDC, arect, TRUE, FALSE);
SelectObject(hDC, hOldBrush);
DeleteObject(hBrush);
}
}
}
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
}
}
int CFlexComboBox::AddString(LPCTSTR str)
{
return m_ListBox.AddString(str);
}
LRESULT CFlexComboBox::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
RECT wrect = {-1, -1, -1, -1};
POINT point = {-1, -1};
BOOL bWithin = FALSE;
switch (msg)
{
case WM_SIZE:
Invalidate();
SetRect();
return 0;
case WM_FLEXLISTBOX:
assert(lParam == (LPARAM)(LPVOID)&m_ListBox);
switch (wParam)
{
case FLBN_FINALSEL:
StateEvent(FCBSE_UPLIST);
break;
case FLBN_CANCEL:
StateEvent(FCBSE_DOWNOFF);
break;
}
return 0;
// make sure flexwnd doesn't do ANYTHING with our mouse messages
case WM_MOUSEMOVE:
// We initialize the tooltip to current selection text if the selected text is too long to fit.
RECT rect;
GetClientRect(&rect);
rect.right = rect.right - (rect.bottom - rect.top);
rect.left++;
rect.top++;
rect.bottom--;
RECT ResultRect;
ResultRect = rect;
HDC hDC;
hDC = CreateCompatibleDC(NULL);
if (hDC)
{
LPTSTR lpText = (LPTSTR)GetText();
if (lpText)
{
DrawText(hDC, lpText, -1, &ResultRect, DT_NOPREFIX|DT_CALCRECT);
}
DeleteDC(hDC);
}
if (rect.right < ResultRect.right || rect.bottom < ResultRect.bottom)
{
CFlexWnd::s_ToolTip.SetToolTipParent(GetParent(m_hWnd));
TOOLTIPINITPARAM ttip;
ttip.hWndParent = GetParent(m_hWnd);
ttip.iSBWidth = 0;
ttip.dwID = 0;
ttip.hWndNotify = m_hWnd;
ttip.tszCaption = m_ListBox.GetSelText();
CFlexToolTip::UpdateToolTipParam(ttip);
}
Notify(FCBN_MOUSEOVER);
case WM_LBUTTONUP:
case WM_LBUTTONDOWN:
case WM_RBUTTONUP:
case WM_RBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
if (msg == WM_LBUTTONDOWN)
{
HWND hWndParent;
hWndParent = GetParent(hWnd);
SendMessage(hWndParent, WM_UNHIGHLIGHT, 0, 0); // Send click message to page to unhighlight callout
}
GetClientRect(&wrect);
point.x = int(LOWORD(lParam));
point.y = int(HIWORD(lParam));
bWithin = PtInRect(&wrect, point);
break;
case WM_TIMER:
case WM_CAPTURECHANGED:
break;
default:
return CFlexWnd::WndProc(hWnd, msg, wParam, lParam);
}
switch (msg)
{
case WM_LBUTTONDOWN:
if (!GetReadOnly())
StateEvent(bWithin ? FCBSE_DOWN : FCBSE_DOWNOFF);
break;
case WM_LBUTTONUP:
if (!GetReadOnly())
StateEvent(bWithin ? FCBSE_UPBOX : FCBSE_UPOFF);
break;
}
return 0;
}
RECT CFlexComboBox::GetListBoxRect()
{
HWND hParent = GetParent(m_hWnd);
RECT rect;
GetClientRect(&rect);
BOOL bRet = ClientToScreen(m_hWnd, &rect);
BOOL bRet2 = ScreenToClient(hParent, &rect);
RECT lrect = m_rect;
lrect.top = rect.bottom;
lrect.right -= 12; // UNDONE: remove this line when the clipping is working properly (scroll bars don't appear above other windows)
return lrect;
}
void CFlexComboBox::DoSel()
{
if (m_bInSelMode)
return;
if (m_hWnd == NULL)
return;
FLEXLISTBOXCREATESTRUCT cs;
cs.dwSize = sizeof(FLEXLISTBOXCREATESTRUCT);
cs.dwFlags = m_dwListBoxFlags;
cs.hWndParent = GetParent(m_hWnd);
cs.hWndNotify = m_hWnd;
cs.bVisible = FALSE;
cs.rect = GetListBoxRect();
cs.hFont = m_hFont;
cs.rgbText = m_rgbText;
cs.rgbBk = m_rgbBk;
cs.rgbSelText = m_rgbSelText;
cs.rgbSelBk = m_rgbSelBk;
cs.rgbFill = m_rgbFill;
cs.rgbLine = m_rgbLine;
cs.nSBWidth = m_nSBWidth;
m_OldSel = m_ListBox.GetSel();
m_bInSelMode = m_ListBox.Create(&cs);
if (m_bInSelMode)
SetWindowPos(m_ListBox.m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
}
void CFlexComboBox::Notify(int code)
{
if (!m_hWndNotify)
return;
SendMessage(m_hWndNotify, WM_FLEXCOMBOBOX,
(WPARAM)code, (LPARAM)(LPVOID)this);
}
RECT CFlexComboBox::GetRect(const RECT &rect)
{
int h = GetTextHeight(m_hFont);
RECT ret = {rect.left, rect.top, rect.right, rect.top + h + 2};
return ret;
}
RECT CFlexComboBox::GetRect()
{
RECT rect;
GetClientRect(&rect);
return GetRect(rect);
}
void CFlexComboBox::SetFont(HFONT hFont)
{
m_hFont = hFont;
if (m_hWnd == NULL)
return;
Invalidate();
SetRect();
}
void CFlexComboBox::SetRect()
{
if (m_hWnd == NULL)
return;
RECT rect = GetRect();
SetWindowPos(m_hWnd, NULL, rect.left, rect.top, rect.right, rect.bottom, SWP_NOZORDER | SWP_NOMOVE);
}
void CFlexComboBox::SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line)
{
m_rgbText = text;
m_rgbBk = bk;
m_rgbSelText = seltext;
m_rgbSelBk = selbk;
m_rgbFill = fill;
m_rgbLine = line;
Invalidate();
}
void CFlexComboBox::StateEvent(FCBSTATEEVENT e)
{
if (e == FCBSE_DOWNOFF)
{
SetState(FCBS_CANCEL);
return;
}
switch (m_eCurState)
{
case FCBS_CLOSED:
if (e == FCBSE_DOWN)
SetState(FCBS_OPENDOWN);
break;
case FCBS_OPENDOWN:
switch (e)
{
case FCBSE_UPLIST:
SetState(FCBS_SELECT);
break;
case FCBSE_UPBOX:
SetState(FCBS_OPENUP);
break;
case FCBSE_UPOFF:
SetState(FCBS_CANCEL);
break;
}
case FCBS_OPENUP:
if (e == FCBSE_DOWN)
SetState(FCBS_OPENDOWN);
break;
default:
assert(0);
return;
}
}
void CFlexComboBox::SetState(FCBSTATE s)
{
FCBSTATE eOldState = m_eCurState;
m_eCurState = s;
switch (s)
{
case FCBS_OPENUP:
if (eOldState == FCBS_CLOSED)
DoSel();
return;
case FCBS_OPENDOWN:
if (eOldState == FCBS_CLOSED)
DoSel();
m_ListBox.StartSel();
return;
case FCBS_CANCEL:
m_ListBox.SetSel(m_OldSel);
CFlexWnd::s_ToolTip.SetEnable(FALSE);
SetState(FCBS_CLOSED);
return;
case FCBS_SELECT:
CFlexWnd::s_ToolTip.SetEnable(FALSE);
Invalidate();
Notify(FCBN_SELCHANGE);
SetState(FCBS_CLOSED);
return;
case FCBS_CLOSED:
if (eOldState != FCBS_CLOSED)
m_ListBox.Destroy();
m_bInSelMode = FALSE;
Invalidate();
return;
}
}

View File

@@ -0,0 +1,115 @@
//-----------------------------------------------------------------------------
// File: flexcombobox.h
//
// Desc: Implements a combo box control similar to Windows combo box.
// CFlexComboBox is derived from CFlexWnd. It is used by the page
// for player list and genre list. When the combo box is open,
// CFlexComboBox uses a CFlexListBox for the list window.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __FLEXCOMBOBOX_H__
#define __FLEXCOMBOBOX_H__
#include "flexlistbox.h"
#define FCBF_DEFAULT 0
enum {
FCBN_SELCHANGE,
FCBN_MOUSEOVER
};
struct FLEXCOMBOBOXCREATESTRUCT {
DWORD dwSize;
DWORD dwFlags;
DWORD dwListBoxFlags;
HWND hWndParent;
HWND hWndNotify;
BOOL bVisible;
RECT rect;
HFONT hFont;
COLORREF rgbText, rgbBk, rgbSelText, rgbSelBk, rgbFill, rgbLine;
int nSBWidth;
};
class CFlexComboBox : public CFlexWnd
{
public:
CFlexComboBox();
~CFlexComboBox();
// creation
BOOL Create(FLEXCOMBOBOXCREATESTRUCT *);
// cosmetics
void SetFont(HFONT hFont);
void SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line);
// setup
int AddString(LPCTSTR); // returns index
// interaction
void SetSel(int i);
int GetSel();
LPCTSTR GetText();
protected:
virtual void OnPaint(HDC hDC);
virtual LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
HWND m_hWndNotify;
COLORREF m_rgbText, m_rgbBk, m_rgbSelText, m_rgbSelBk, m_rgbFill, m_rgbLine;
HFONT m_hFont;
int m_nSBWidth;
int m_nTextHeight;
DWORD m_dwFlags;
DWORD m_dwListBoxFlags;
enum FCBSTATEEVENT {
FCBSE_DOWN,
FCBSE_UPBOX,
FCBSE_UPLIST,
FCBSE_UPOFF,
FCBSE_DOWNOFF
};
enum FCBSTATE {
FCBS_CLOSED,
FCBS_OPENDOWN,
FCBS_OPENUP,
FCBS_CANCEL,
FCBS_SELECT
};
FCBSTATE m_eCurState;
void StateEvent(FCBSTATEEVENT e);
void SetState(FCBSTATE s);
int m_OldSel;
RECT GetRect(const RECT &);
RECT GetRect();
RECT GetListBoxRect();
void SetRect();
RECT m_rect;
void InternalPaint(HDC hDC);
void Notify(int code);
CFlexListBox m_ListBox;
BOOL m_bInSelMode;
void DoSel();
};
CFlexComboBox *CreateFlexComboBox(FLEXCOMBOBOXCREATESTRUCT *pcs);
#endif //__FLEXCOMBOBOX_H__

View File

@@ -0,0 +1,320 @@
//-----------------------------------------------------------------------------
// File: flexinfobox.cpp
//
// Desc: Implements a simple text box that displays a text string.
// CFlexInfoBox is derived from CFlexWnd. It is used by the page
// for displaying direction throughout the UI. The strings are
// stored as resources. The class has a static buffer which will
// be filled with the string by the resource API when needed.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
CFlexInfoBox::CFlexInfoBox() :
m_iCurIndex(-1),
m_rgbText(RGB(255,255,255)),
m_rgbBk(RGB(0,0,0)),
m_rgbSelText(RGB(0,0,255)),
m_rgbSelBk(RGB(0,0,0)),
m_rgbFill(RGB(0,0,255)),
m_rgbLine(RGB(0,255,255)),
m_hFont(NULL),
m_bVertSB(FALSE),
m_nSBWidth(11)
{
m_TextRect.top = 0;
m_TextRect.left = 0;
m_TextRect.bottom = 0;
m_TextRect.right = 0;
}
CFlexInfoBox::~CFlexInfoBox()
{
}
BOOL CFlexInfoBox::Create(HWND hParent, const RECT &rect, BOOL bVisible)
{
if (!CFlexWnd::Create(hParent, rect, bVisible))
return FALSE;
FLEXSCROLLBARCREATESTRUCT sbcs;
sbcs.dwSize = sizeof(FLEXSCROLLBARCREATESTRUCT);
sbcs.dwFlags = FSBF_VERT;
sbcs.min = 0;
sbcs.max = 3;
sbcs.page = 1;
sbcs.pos = 1;
sbcs.hWndParent = m_hWnd;
sbcs.hWndNotify = m_hWnd;
RECT rc = {0, 0, 1, 1};
sbcs.rect = rc;
sbcs.bVisible = FALSE;
return m_VertSB.Create(&sbcs);
}
void CFlexInfoBox::SetText(int iIndex)
{
if (iIndex == m_iCurIndex)
return;
// Load the string from resource
LoadString(g_hModule, iIndex, m_tszText, MAX_PATH);
// Calculate the rectangle for text
RECT titlerc;
m_TextRect = g_InfoWndRect;
OffsetRect(&m_TextRect, -m_TextRect.left, -m_TextRect.top);
InflateRect(&m_TextRect, -1, -1);
titlerc = m_TextRect;
HDC hDC = CreateCompatibleDC(NULL);
if (hDC)
{
TCHAR tszResourceString[MAX_PATH];
LoadString(g_hModule, IDS_INFO_TITLE, tszResourceString, MAX_PATH);
DrawText(hDC, tszResourceString, -1, &titlerc, DT_CENTER|DT_NOPREFIX|DT_CALCRECT);
m_TextRect.top = titlerc.bottom + 1;
m_TextWinRect = m_TextRect;
DrawText(hDC, m_tszText, -1, &m_TextRect, DT_CENTER|DT_NOPREFIX|DT_CALCRECT|DT_WORDBREAK);
if (m_TextRect.bottom + 1 > g_InfoWndRect.bottom - g_InfoWndRect.top)
{
// Text too long. We need a scroll bar.
m_TextRect.right -= m_nSBWidth;
DrawText(hDC, m_tszText, -1, &m_TextRect, DT_CENTER|DT_NOPREFIX|DT_CALCRECT|DT_WORDBREAK);
SetVertSB(TRUE);
} else
SetVertSB(FALSE);
DeleteDC(hDC);
}
m_iCurIndex = iIndex;
Invalidate();
}
void CFlexInfoBox::SetFont(HFONT hFont)
{
m_hFont = hFont;
if (m_hWnd == NULL)
return;
Invalidate();
}
void CFlexInfoBox::SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line)
{
m_rgbText = text;
m_rgbBk = bk;
m_rgbSelText = seltext;
m_rgbSelBk = selbk;
m_rgbFill = fill;
m_rgbLine = line;
m_VertSB.SetColors(m_rgbBk, m_rgbFill, m_rgbLine);
Invalidate();
}
void CFlexInfoBox::SetRect()
{
if (m_hWnd == NULL)
return;
RECT rect = GetRect();
SetWindowPos(m_hWnd, NULL, rect.left, rect.top, rect.right, rect.bottom, SWP_NOZORDER | SWP_NOMOVE);
}
RECT CFlexInfoBox::GetRect(const RECT &rect)
{
int h = GetTextHeight(m_hFont);
RECT ret = {rect.left, rect.top, rect.right, rect.top + h + 2};
return ret;
}
RECT CFlexInfoBox::GetRect()
{
RECT rect;
GetClientRect(&rect);
return GetRect(rect);
}
void CFlexInfoBox::OnPaint(HDC hDC)
{
HDC hBDC = NULL, hODC = NULL;
CBitmap *pbm = NULL;
if (!InRenderMode())
{
hODC = hDC;
pbm = CBitmap::Create(GetClientSize(), RGB(0,0,0), hDC);
if (pbm != NULL)
{
hBDC = pbm->BeginPaintInto();
if (hBDC != NULL)
{
hDC = hBDC;
}
}
}
InternalPaint(hDC);
if (!InRenderMode())
{
if (pbm != NULL)
{
if (hBDC != NULL)
{
pbm->EndPaintInto(hBDC);
pbm->Draw(hODC);
}
delete pbm;
}
}
}
void CFlexInfoBox::InternalPaint(HDC hDC)
{
TCHAR tszResourceString[MAX_PATH];
HGDIOBJ hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbLine);
if (hPen != NULL)
{
HGDIOBJ hOldPen = SelectObject(hDC, hPen);
HGDIOBJ hBrush = (HGDIOBJ)CreateSolidBrush(m_rgbBk);
if (hBrush != NULL)
{
HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
RECT rect = {0,0,0,0}, titlerc;
GetClientRect(&rect);
titlerc = rect;
Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
InflateRect(&rect, -1, -1);
SetBkMode(hDC, TRANSPARENT);
LoadString(g_hModule, IDS_INFO_TITLE, tszResourceString, MAX_PATH);
// Draw the message text
SetTextColor(hDC, m_rgbText);
rect = m_TextRect;
// Offset the rectangle to account for scroll bar
if (m_bVertSB)
{
OffsetRect(&rect, 0, -m_VertSB.GetPos());
}
DrawText(hDC, m_tszText, -1, &rect, DT_LEFT|DT_NOPREFIX|DT_WORDBREAK);
GetClientRect(&rect);
InflateRect(&rect, -1, -1);
SetTextColor(hDC, m_rgbLine); // User line color for Information title
// Get the title area rantangle
DrawText(hDC, tszResourceString, -1, &titlerc, DT_CENTER|DT_NOPREFIX|DT_CALCRECT);
// Adjust right edge position to old value
titlerc.right = rect.right + 1;
// Draw a rectangle around the title area.
Rectangle(hDC, titlerc.left, titlerc.top, titlerc.right, titlerc.bottom);
// Draw title text (Information)
DrawText(hDC, tszResourceString, -1, &titlerc, DT_CENTER|DT_NOPREFIX);
SelectObject(hDC, hOldBrush);
DeleteObject(hBrush);
}
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
}
}
void CFlexInfoBox::SetVertSB(BOOL bSet)
{
if (!bSet && !m_bVertSB)
return;
m_bVertSB = bSet;
if (m_hWnd == NULL)
return;
SetVertSB();
}
void CFlexInfoBox::SetVertSB()
{
if (m_bVertSB)
{
SetSBValues();
SIZE client = GetClientSize();
client.cy = m_TextWinRect.bottom - m_TextWinRect.top;
SetWindowPos(m_VertSB.m_hWnd, NULL, client.cx - m_nSBWidth - 1, m_TextRect.top, m_nSBWidth, client.cy - 1, SWP_NOZORDER);
}
ShowWindow(m_VertSB.m_hWnd, m_bVertSB ? SW_SHOW : SW_HIDE);
}
void CFlexInfoBox::SetSBValues()
{
if (m_hWnd == NULL)
return;
m_VertSB.SetValues(0, m_TextRect.bottom - m_TextRect.top, m_TextWinRect.bottom - m_TextWinRect.top, 0);
}
void CFlexInfoBox::OnWheel(POINT point, WPARAM wParam)
{
if (!m_bVertSB) return;
if (m_VertSB.GetMin() == m_VertSB.GetMax()) return;
int nPage = MulDiv(m_VertSB.GetPage(), 9, 10) >> 1; // Half a page at a time
if ((int)wParam >= 0)
m_VertSB.AdjustPos(-nPage);
else
m_VertSB.AdjustPos(nPage);
Invalidate();
}
LRESULT CFlexInfoBox::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_FLEXVSCROLL:
{
int code = (int)wParam;
CFlexScrollBar *pSB = (CFlexScrollBar *)lParam;
if (!pSB)
return 0;
int nLine = 1;
int nPage = MulDiv(pSB->GetPage(), 9, 10);
switch (code)
{
case SB_LINEUP: pSB->AdjustPos(-nLine); break;
case SB_LINEDOWN: pSB->AdjustPos(nLine); break;
case SB_PAGEUP: pSB->AdjustPos(-nPage); break;
case SB_PAGEDOWN: pSB->AdjustPos(nPage); break;
case SB_THUMBTRACK: pSB->SetPos(pSB->GetThumbPos()); break;
case SB_ENDSCROLL:
::ReleaseCapture();
break;
}
Invalidate();
return 0;
}
default:
if (msg == WM_LBUTTONDOWN)
{
HWND hWndParent;
hWndParent = GetParent(hWnd);
SendMessage(hWndParent, WM_UNHIGHLIGHT, 0, 0); // Send click message to page to unhighlight callout
}
return CFlexWnd::WndProc(hWnd, msg, wParam, lParam);
}
return 0;
}

View File

@@ -0,0 +1,56 @@
//-----------------------------------------------------------------------------
// File: flexinfobox.h
//
// Desc: Implements a simple text box that displays a text string.
// CFlexInfoBox is derived from CFlexWnd. It is used by the page
// for displaying direction throughout the UI. The strings are
// stored as resources. The class has a static buffer which will
// be filled with the string by the resource API when needed.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __FLEXINFOBOX_H__
#define __FLEXINFOBOX_H__
class CFlexInfoBox : public CFlexWnd
{
TCHAR m_tszText[MAX_PATH]; // Text string of the message
int m_iCurIndex; // Current text index
COLORREF m_rgbText, m_rgbBk, m_rgbSelText, m_rgbSelBk, m_rgbFill, m_rgbLine;
HFONT m_hFont;
RECT m_TextRect;
RECT m_TextWinRect;
int m_nSBWidth;
CFlexScrollBar m_VertSB;
BOOL m_bVertSB;
void SetVertSB(BOOL bSet);
void SetVertSB();
void SetSBValues();
void SetRect();
void InternalPaint(HDC hDC);
RECT GetRect(const RECT &);
RECT GetRect();
protected:
virtual LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
virtual void OnPaint(HDC hDC);
virtual void OnWheel(POINT point, WPARAM wParam);
public:
CFlexInfoBox();
virtual ~CFlexInfoBox();
BOOL Create(HWND hParent, const RECT &rect, BOOL bVisible);
void SetText(int iIndex);
// cosmetics
void SetFont(HFONT hFont);
void SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line);
};
#endif

View File

@@ -0,0 +1,592 @@
//-----------------------------------------------------------------------------
// File: flexlistbox.cpp
//
// Desc: Implements a list box control that can display a list of text strings,
// each can be selected by mouse. The class CFlexListBox is derived from
// CFlexWnd. It is used by the class CFlexComboBox when it needs to
// expand to show the list of choices.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
CFlexListBox::CFlexListBox() :
m_nTextHeight(-1),
m_hWndNotify(NULL),
m_rgbText(RGB(255,255,255)),
m_rgbBk(RGB(0,0,0)),
m_rgbSelText(RGB(0,0,255)),
m_rgbSelBk(RGB(0,0,0)),
m_rgbFill(RGB(0,0,255)),
m_rgbLine(RGB(0,255,255)),
m_dwFlags(0),
m_nTopIndex(0),
m_nSBWidth(11),
m_hFont(NULL),
m_bOpenClick(FALSE),
m_bDragging(FALSE),
m_bCapture(FALSE),
m_nSelItem(-1),
m_bVertSB(FALSE)
{
}
CFlexListBox::~CFlexListBox()
{
}
CFlexListBox *CreateFlexListBox(FLEXLISTBOXCREATESTRUCT *pcs)
{
CFlexListBox *psb = new CFlexListBox;
if (psb && psb->Create(pcs))
return psb;
delete psb;
return NULL;
}
BOOL CFlexListBox::CreateForSingleSel(FLEXLISTBOXCREATESTRUCT *pcs)
{
if (!Create(pcs))
return FALSE;
StartSel();
return TRUE;
}
BOOL CFlexListBox::Create(FLEXLISTBOXCREATESTRUCT *pcs)
{
if (this == NULL)
return FALSE;
if (m_hWnd)
Destroy();
if (pcs == NULL)
return FALSE;
if (pcs->dwSize != sizeof(FLEXLISTBOXCREATESTRUCT))
return FALSE;
m_hWndNotify = pcs->hWndNotify ? pcs->hWndNotify : pcs->hWndParent;
m_dwFlags = pcs->dwFlags;
SetFont(pcs->hFont);
SetColors(pcs->rgbText, pcs->rgbBk, pcs->rgbSelText, pcs->rgbSelBk, pcs->rgbFill, pcs->rgbLine);
m_VertSB.SetColors(pcs->rgbBk, pcs->rgbFill, pcs->rgbLine);
m_nSBWidth = pcs->nSBWidth;
if (!CFlexWnd::Create(pcs->hWndParent, pcs->rect, FALSE))
return FALSE;
FLEXSCROLLBARCREATESTRUCT sbcs;
sbcs.dwSize = sizeof(FLEXSCROLLBARCREATESTRUCT);
sbcs.dwFlags = FSBF_VERT;
sbcs.min = 0;
sbcs.max = 3;
sbcs.page = 1;
sbcs.pos = 1;
sbcs.hWndParent = m_hWnd;
sbcs.hWndNotify = m_hWnd;
RECT rect = {0, 0, 1, 1};
sbcs.rect = rect;
sbcs.bVisible = FALSE;
m_VertSB.Create(&sbcs);
Calc();
// show if we want it shown
if (pcs->bVisible)
ShowWindow(m_hWnd, SW_SHOW);
if (m_bVertSB)
SetVertSB();
// TODO: make sure that creation sends no notifications.
// all initial notifications should be sent here.
return TRUE;
}
void CFlexListBox::Calc()
{
// handle getting text height
if (m_nTextHeight == -1)
{
m_nTextHeight = GetTextHeight(m_hFont);
Invalidate();
assert(m_nTextHeight != -1);
}
// don't do the rest unless we've been created
if (m_hWnd == NULL)
return;
// handle integral height
int iUsedHeight = m_ItemArray.GetSize() * m_nTextHeight;
// If more than max height, use the max height
if (iUsedHeight > g_UserNamesRect.bottom - g_UserNamesRect.top)
iUsedHeight = g_UserNamesRect.bottom - g_UserNamesRect.top;
SIZE client = GetClientSize();
int fit = iUsedHeight / m_nTextHeight;
if (fit < 1)
fit = 1;
int setheight = (m_dwFlags & FLBF_INTEGRALHEIGHT) ? fit * m_nTextHeight : iUsedHeight;
if (setheight != client.cy)
SetWindowPos(m_hWnd, NULL, 0, 0, client.cx, setheight,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER);
// handle scroll bar
SetVertSB(m_ItemArray.GetSize() > fit);
}
void CFlexListBox::SetFont(HFONT hFont)
{
m_hFont = hFont;
m_nTextHeight = -1;
Calc();
}
void CFlexListBox::OnPaint(HDC hDC)
{
HDC hBDC = NULL, hODC = NULL;
CBitmap *pbm = NULL;
if (!InRenderMode())
{
hODC = hDC;
pbm = CBitmap::Create(GetClientSize(), RGB(0,0,0), hDC);
if (pbm != NULL)
{
hBDC = pbm->BeginPaintInto();
if (hBDC != NULL)
{
hDC = hBDC;
}
}
}
InternalPaint(hDC);
if (!InRenderMode())
{
if (pbm != NULL)
{
if (hBDC != NULL)
{
pbm->EndPaintInto(hBDC);
pbm->Draw(hODC);
}
delete pbm;
}
}
}
void CFlexListBox::InternalPaint(HDC hDC)
{
if (m_nTextHeight == -1)
return;
SIZE client = GetClientSize();
RECT rc = {0,0,0,0};
GetClientRect(&rc);
HGDIOBJ hPen, hOldPen, hBrush, hOldBrush;
hPen= (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbBk);
if (hPen != NULL)
{
hOldPen = SelectObject(hDC, hPen);
hBrush = CreateSolidBrush(m_rgbBk);
if (hBrush != NULL)
{
hOldBrush = SelectObject(hDC, hBrush);
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom); // Paint entire window black first.
if (!m_bVertSB)
m_nTopIndex = 0;
int iLastY;
for (int at = 0, i = m_nTopIndex; at < client.cy; i++, at += m_nTextHeight)
{
RECT rect = {0, at, client.cx, at + m_nTextHeight};
if (i < m_ItemArray.GetSize())
{
BOOL bSel = m_ItemArray[i].bSelected;
SetTextColor(hDC, bSel ? m_rgbSelText : m_rgbText);
SetBkColor(hDC, bSel ? m_rgbSelBk : m_rgbBk);
DrawText(hDC, m_ItemArray[i].GetText(), -1, &rect, DT_NOPREFIX);
iLastY = at + m_nTextHeight;
}
}
SelectObject(hDC, hOldBrush);
DeleteObject(hBrush);
}
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
}
// Draw an outline around the box
hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbLine);
if (hPen != NULL)
{
hOldPen = SelectObject(hDC, hPen);
hOldBrush = SelectObject(hDC, GetStockObject(NULL_BRUSH));
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
}
}
int CFlexListBox::AddString(LPCTSTR str)
{
int newIndex = m_ItemArray.GetSize();
m_ItemArray.SetSize(newIndex + 1);
FLEXLISTBOXITEM &i = m_ItemArray[newIndex];
i.SetText(str);
i.bSelected = FALSE;
SetSBValues();
Calc();
Invalidate();
return newIndex;
}
void CFlexListBox::StartSel()
{
if (m_bDragging)
return;
SetTimer(m_hWnd, 5, 200, NULL);
m_bOpenClick = TRUE; // Initial click on the combobox
m_bDragging = TRUE;
m_bCapture = TRUE;
SetCapture();
}
void CFlexListBox::OnWheel(POINT point, WPARAM wParam)
{
if (!m_bVertSB) return;
int nPage = MulDiv(m_VertSB.GetPage(), 9, 10) >> 1; // Half a page at a time
if ((int)wParam >= 0)
m_VertSB.AdjustPos(-nPage);
else
m_VertSB.AdjustPos(nPage);
m_nTopIndex = m_VertSB.GetPos();
if (m_nTopIndex < 0)
m_nTopIndex = 0;
Invalidate();
}
LRESULT CFlexListBox::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// first handle scroll bar messages
switch (msg)
{
case WM_FLEXVSCROLL:
int code = (int)wParam;
CFlexScrollBar *pSB = (CFlexScrollBar *)lParam;
if (!pSB)
return 0;
int nLine = 1;
int nPage = MulDiv(pSB->GetPage(), 9, 10);
switch (code)
{
case SB_LINEUP: pSB->AdjustPos(-nLine); break;
case SB_LINEDOWN: pSB->AdjustPos(nLine); break;
case SB_PAGEUP: pSB->AdjustPos(-nPage); break;
case SB_PAGEDOWN: pSB->AdjustPos(nPage); break;
case SB_THUMBTRACK: pSB->SetPos(pSB->GetThumbPos()); break;
case SB_ENDSCROLL:
SetCapture(); // Recapture after the scroll bar releases the capture.
break;
}
switch (msg)
{
case WM_FLEXVSCROLL:
m_nTopIndex = pSB->GetPos();
if (m_nTopIndex < 0)
m_nTopIndex = 0;
break;
}
Invalidate();
return 0;
}
// now non-scrolly input
switch (msg)
{
case WM_SIZE:
SetSBValues();
Calc();
Invalidate();
return 0;
// make sure flexwnd doesn't do ANYTHING with our mouse messages
case WM_MOUSEMOVE:
case WM_LBUTTONUP:
case WM_LBUTTONDOWN:
case WM_RBUTTONUP:
case WM_RBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
{
POINT point = {int(signed short(LOWORD(lParam))), int(signed short(HIWORD(lParam)))};
m_point = point;
}
case WM_TIMER:
case WM_CAPTURECHANGED:
break;
default:
return CFlexWnd::WndProc(hWnd, msg, wParam, lParam);
}
switch (msg)
{
case WM_LBUTTONDOWN:
// Check if we clicked the scroll bar area. If so, send the click to the scroll bar.
RECT rc;
m_VertSB.GetClientRect(&rc);
ClientToScreen(m_VertSB.m_hWnd, &rc);
ScreenToClient(m_hWnd, &rc);
if (PtInRect(&rc, m_point))
{
POINT point = {int(signed short(LOWORD(lParam))), int(signed short(HIWORD(lParam)))};
ClientToScreen(m_hWnd, &point);
ScreenToClient(m_VertSB.m_hWnd, &point);
PostMessage(m_VertSB.m_hWnd, WM_LBUTTONDOWN, wParam, point.x + (point.y << 16)); // This will make it lose capture.
} else
StartSel();
break;
case WM_MOUSEMOVE:
case WM_LBUTTONUP:
if (!m_bDragging)
break;
if (m_nTextHeight == -1)
break;
case WM_TIMER:
if (m_bDragging || msg != WM_TIMER)
{
int adj = m_point.y < 0 ? -1 : 0;
SelectAndShowSingleItem(adj + m_point.y / m_nTextHeight + m_nTopIndex, msg != WM_MOUSEMOVE);
Notify(FLBN_SEL);
}
// Check if the mouse cursor is within the listbox rectangle. If not, don't show the tooltip.
if (msg == WM_MOUSEMOVE)
{
RECT rect;
GetClientRect(&rect);
POINT pt;
GetCursorPos(&pt);
ScreenToClient(m_hWnd, &pt);
if (!PtInRect(&rect, pt))
{
CFlexWnd::s_ToolTip.SetToolTipParent(NULL);
CFlexWnd::s_ToolTip.SetEnable(FALSE);
}
}
break;
}
switch (msg)
{
case WM_CAPTURECHANGED:
if ((HWND)lParam == m_VertSB.m_hWnd) // If the scroll bar is getting the capture, we do not clean up.
break;
case WM_LBUTTONUP:
if (m_bOpenClick)
{
m_bOpenClick = FALSE; // If this is the result of clicking the combobox window, don't release capture.
break;
}
if (m_bCapture)
{
m_bCapture = FALSE;
KillTimer(m_hWnd, 5);
ReleaseCapture();
m_bDragging = FALSE;
BOOL bCancel = TRUE;
if (msg == WM_LBUTTONUP)
{
RECT wrect;
GetClientRect(&wrect);
if (PtInRect(&wrect, m_point))
bCancel = FALSE;
}
Notify(bCancel ? FLBN_CANCEL : FLBN_FINALSEL);
}
break;
}
return 0;
}
void CFlexListBox::SelectAndShowSingleItem(int i, BOOL bScroll)
{
int nItems = m_ItemArray.GetSize();
if (nItems < 1)
{
m_nSelItem = i; // We have to update m_nSelItem even if there is no items because the username combobox
// is not initialized when there is only 1 user. Selection of user 0 is assumed.
return;
}
if (i < 0)
i = 0;
if (i >= nItems)
i = nItems - 1;
if (m_nSelItem >= 0 && m_nSelItem < nItems)
m_ItemArray[m_nSelItem].bSelected = FALSE;
m_nSelItem = i;
m_ItemArray[m_nSelItem].bSelected = TRUE;
if (bScroll)
{
SIZE client = GetClientSize();
int nBottomIndex = m_nTopIndex + client.cy / m_nTextHeight - 1;
if (m_nSelItem < m_nTopIndex)
m_nTopIndex = m_nSelItem;
assert(m_nTopIndex >= 0);
if (m_nSelItem > nBottomIndex)
{
m_nTopIndex += m_nSelItem - nBottomIndex + 1;
nBottomIndex = m_nSelItem + 1;
}
if (nBottomIndex > nItems - 1)
m_nTopIndex -= nBottomIndex - nItems + 1;
if (m_nTopIndex < 0)
m_nTopIndex = 0;
if (m_nTopIndex >= nItems)
m_nTopIndex = nItems - 1;
assert(m_nTopIndex >= 0 && m_nTopIndex < nItems);
}
if (m_bVertSB)
SetSBValues();
SIZE client = GetClientSize();
int nBottomIndex = m_nTopIndex + client.cy / m_nTextHeight - 1;
int iToolTipIndex = m_nSelItem;
// Make sure that we don't display tooltip for items outside the listbox window
if (iToolTipIndex > nBottomIndex)
iToolTipIndex = nBottomIndex;
if (iToolTipIndex < m_nTopIndex)
iToolTipIndex = m_nTopIndex;
// Create and initialize a tooltip if the text is too long to fit.
RECT rect = {0, 0, client.cx, m_nTextHeight};
RECT ResultRect = rect;
HDC hDC = CreateCompatibleDC(NULL);
if (hDC)
{
DrawText(hDC, m_ItemArray[iToolTipIndex].GetText(), -1, &ResultRect, DT_NOPREFIX|DT_CALCRECT);
DeleteDC(hDC);
}
if (ResultRect.right > rect.right)
{
TOOLTIPINITPARAM ttip;
ttip.hWndParent = GetParent(m_hWnd);
ttip.iSBWidth = m_nSBWidth;
ttip.dwID = iToolTipIndex;
ttip.hWndNotify = m_hWnd;
ttip.tszCaption = GetSelText();
CFlexToolTip::UpdateToolTipParam(ttip);
}
Invalidate();
}
void CFlexListBox::Notify(int code)
{
if (!m_hWndNotify)
return;
SendMessage(m_hWndNotify, WM_FLEXLISTBOX,
(WPARAM)code, (LPARAM)(LPVOID)this);
}
void CFlexListBox::SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line)
{
m_rgbText = text;
m_rgbBk = bk;
m_rgbSelText = seltext;
m_rgbSelBk = selbk;
m_rgbFill = fill;
m_rgbLine = line;
Invalidate();
}
void CFlexListBox::SetVertSB(BOOL bSet)
{
if (bEq(bSet, m_bVertSB))
return;
m_bVertSB = bSet;
if (m_hWnd == NULL)
return;
SetVertSB();
}
void CFlexListBox::SetVertSB()
{
if (m_bVertSB)
{
SetSBValues();
SIZE client = GetClientSize();
SetWindowPos(m_VertSB.m_hWnd, NULL, client.cx - m_nSBWidth - 1, 0, m_nSBWidth, client.cy - 1, SWP_NOZORDER);
}
ShowWindow(m_VertSB.m_hWnd, m_bVertSB ? SW_SHOW : SW_HIDE);
}
void CFlexListBox::SetSBValues()
{
if (m_hWnd == NULL)
return;
SIZE client = GetClientSize();
int fit = client.cy / m_nTextHeight;
m_VertSB.SetValues(0, m_ItemArray.GetSize(), fit, m_nTopIndex);
}
LPCTSTR CFlexListBox::GetSelText()
{
if (m_nSelItem < 0 || m_nSelItem >= m_ItemArray.GetSize())
return NULL;
return m_ItemArray[m_nSelItem].GetText();
}
int CFlexListBox::GetSel()
{
return m_nSelItem;
}

View File

@@ -0,0 +1,124 @@
//-----------------------------------------------------------------------------
// File: flexlistbox.h
//
// Desc: Implements a list box control that can display a list of text strings,
// each can be selected by mouse. The class CFlexListBox is derived from
// CFlexWnd. It is used by the class CFlexComboBox when it needs to
// expand to show the list of choices.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __FLEXLISTBOX_H__
#define __FLEXLISTBOX_H__
#include "flexscrollbar.h"
#define FLBF_INTEGRALHEIGHT 0x00000001
#define FLBF_DEFAULT (FLBF_INTEGRALHEIGHT)
enum {
FLBN_SEL,
FLBN_FINALSEL,
FLBN_CANCEL
};
struct FLEXLISTBOXCREATESTRUCT {
DWORD dwSize;
DWORD dwFlags;
HWND hWndParent;
HWND hWndNotify;
BOOL bVisible;
RECT rect;
HFONT hFont;
COLORREF rgbText, rgbBk, rgbSelText, rgbSelBk, rgbFill, rgbLine;
int nSBWidth;
};
struct FLEXLISTBOXITEM {
FLEXLISTBOXITEM() : pszText(NULL), nID(-1), pData(NULL), bSelected(FALSE) {}
FLEXLISTBOXITEM(const FLEXLISTBOXITEM &i) {nID = i.nID; pData = i.pData; bSelected = i.bSelected; SetText(i.GetText());}
~FLEXLISTBOXITEM() {cleartext();}
void SetText(LPCTSTR str) {cleartext(); pszText = _tcsdup(str);}
LPCTSTR GetText() const {return pszText;}
int nID;
void *pData;
BOOL bSelected;
private:
void cleartext() {if (pszText) free(pszText); pszText = NULL;}
LPTSTR pszText; // allocated
};
class CFlexListBox : public CFlexWnd
{
public:
CFlexListBox();
~CFlexListBox();
// creation
BOOL Create(FLEXLISTBOXCREATESTRUCT *);
BOOL CreateForSingleSel(FLEXLISTBOXCREATESTRUCT *);
// cosmetics
void SetFont(HFONT hFont);
void SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line);
// setup
int AddString(LPCTSTR); // returns index
// interaction
void SelectAndShowSingleItem(int i, BOOL bScroll = TRUE);
void SetSel(int i) {SelectAndShowSingleItem(i, FALSE);}
void StartSel();
LPCTSTR GetSelText();
int GetSel();
protected:
virtual void OnPaint(HDC hDC);
virtual LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
virtual void OnWheel(POINT point, WPARAM wParam);
private:
HWND m_hWndNotify;
CArray<FLEXLISTBOXITEM, FLEXLISTBOXITEM &> m_ItemArray;
COLORREF m_rgbText, m_rgbBk, m_rgbSelText, m_rgbSelBk, m_rgbFill, m_rgbLine;
HFONT m_hFont;
int m_nSBWidth;
int m_nTextHeight;
DWORD m_dwFlags;
int m_nSelItem;
int m_nTopIndex;
void Calc();
void SetVertSB(BOOL);
void SetVertSB();
void SetSBValues();
void InternalPaint(HDC hDC);
void Notify(int code);
POINT m_point;
BOOL m_bOpenClick; // True when user click the combobox to open the listbox. False after that button up msg is processed.
BOOL m_bCapture;
BOOL m_bDragging;
CFlexScrollBar m_VertSB;
BOOL m_bVertSB;
};
CFlexListBox *CreateFlexListBox(FLEXLISTBOXCREATESTRUCT *pcs);
#endif //__FLEXLISTBOX_H__

View File

@@ -0,0 +1,35 @@
//-----------------------------------------------------------------------------
// File: flexmsg.h
//
// Desc: Contains definitions of private messages used by the UI.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __FLEXMSG_H__
#define __FLEXMSG_H__
#define WM_CFGUIRESET (WM_USER + 6)
#ifndef WM_FLEXMSGBASE
#define WM_FLEXMSGBASE (WM_USER + 7)
#endif
#define WM_GETFLEXWND (WM_FLEXMSGBASE + 0)
#define WM_FLEXTREENOTIFY (WM_FLEXMSGBASE + 1)
#define WM_FLEXVSCROLL (WM_FLEXMSGBASE + 2)
#define WM_FLEXHSCROLL (WM_FLEXMSGBASE + 3)
#define WM_FLEXLISTBOX (WM_FLEXMSGBASE + 4)
#define WM_FLEXCOMBOBOX (WM_FLEXMSGBASE + 5)
#define WM_FLEXCHECKBOX (WM_FLEXMSGBASE + 6)
#define WM_DIRENDER (WM_FLEXMSGBASE + 7)
#define WM_UNHIGHLIGHT (WM_FLEXMSGBASE + 8)
#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A
#endif
#endif //__FLEXMSG_H__

View File

@@ -0,0 +1,183 @@
//-----------------------------------------------------------------------------
// File: flexMsgBox.cpp
//
// Desc: Implements a message box control similar to Windows message box
// without the button. CFlexMsgBox is derived from CFlexWnd.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
CFlexMsgBox::CFlexMsgBox() :
m_hWndNotify(NULL),
m_rgbText(RGB(255,255,255)),
m_rgbBk(RGB(0,0,0)),
m_rgbSelText(RGB(0,0,255)),
m_rgbSelBk(RGB(0,0,0)),
m_rgbFill(RGB(0,0,255)),
m_rgbLine(RGB(0,255,255)),
m_hFont(NULL),
m_tszText(NULL)
{
}
CFlexMsgBox::~CFlexMsgBox()
{
delete[] m_tszText;
}
HWND CFlexMsgBox::Create(HWND hParent, const RECT &rect, BOOL bVisible)
{
m_bSent = FALSE;
return CFlexWnd::Create(hParent, rect, bVisible);
}
void CFlexMsgBox::SetText(LPCTSTR tszText)
{
LPTSTR tszTempText = NULL;
if (tszText)
{
tszTempText = new TCHAR[_tcslen(tszText) + 1];
if (!tszTempText) return;
_tcscpy(tszTempText, tszText);
}
delete[] m_tszText;
m_tszText = tszTempText;
}
void CFlexMsgBox::SetFont(HFONT hFont)
{
m_hFont = hFont;
if (m_hWnd == NULL)
return;
Invalidate();
}
void CFlexMsgBox::SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line)
{
m_rgbText = text;
m_rgbBk = bk;
m_rgbSelText = seltext;
m_rgbSelBk = selbk;
m_rgbFill = fill;
m_rgbLine = line;
Invalidate();
}
void CFlexMsgBox::SetRect()
{
if (m_hWnd == NULL)
return;
RECT rect = GetRect();
SetWindowPos(m_hWnd, NULL, rect.left, rect.top, rect.right, rect.bottom, SWP_NOZORDER | SWP_NOMOVE);
}
RECT CFlexMsgBox::GetRect(const RECT &rect)
{
int h = GetTextHeight(m_hFont);
RECT ret = {rect.left, rect.top, rect.right, rect.top + h + 2};
return ret;
}
RECT CFlexMsgBox::GetRect()
{
RECT rect;
GetClientRect(&rect);
return GetRect(rect);
}
void CFlexMsgBox::OnPaint(HDC hDC)
{
HDC hBDC = NULL, hODC = NULL;
CBitmap *pbm = NULL;
if (!InRenderMode())
{
hODC = hDC;
pbm = CBitmap::Create(GetClientSize(), RGB(0,0,0), hDC);
if (pbm != NULL)
{
hBDC = pbm->BeginPaintInto();
if (hBDC != NULL)
{
hDC = hBDC;
}
}
}
InternalPaint(hDC);
if (!InRenderMode())
{
if (pbm != NULL)
{
if (hBDC != NULL)
{
pbm->EndPaintInto(hBDC);
pbm->Draw(hODC);
}
delete pbm;
}
}
// Post reset message to config window now that the msg window is shown, if
// we haven't done so.
if (!m_bSent)
{
HWND hParentWnd = GetParent(m_hWnd);
PostMessage(hParentWnd, WM_CFGUIRESET, 0, 0);
}
// Flag it that we've sent the message.
m_bSent = TRUE;
}
void CFlexMsgBox::InternalPaint(HDC hDC)
{
HGDIOBJ hBrush = (HGDIOBJ)CreateSolidBrush(m_rgbBk);
if (hBrush != NULL)
{
HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
// Create pen for check box
HGDIOBJ hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbLine);
if (hPen != NULL)
{
HGDIOBJ hOldPen = SelectObject(hDC, hPen);
// Erase the background and also draw border
RECT client;
GetClientRect(&client);
Rectangle(hDC, client.left, client.top, client.right, client.bottom);
InflateRect(&client, -1, -1);
// SetBkMode(hDC, TRANSPARENT);
// Draw the message text
SetTextColor(hDC, m_rgbText);
SetBkColor(hDC, m_rgbBk);
DrawText(hDC, m_tszText, -1, &client, DT_CENTER|DT_VCENTER|DT_NOPREFIX|DT_SINGLELINE);
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
}
SelectObject(hDC, hOldBrush);
DeleteObject(hBrush);
}
}
void CFlexMsgBox::Notify(int code)
{
if (!m_hWndNotify)
return;
PostMessage(m_hWndNotify, WM_FLEXCHECKBOX,
(WPARAM)code, (LPARAM)(LPVOID)this);
}

View File

@@ -0,0 +1,46 @@
//-----------------------------------------------------------------------------
// File: flexMsgBox.h
//
// Desc: Implements a message box control similar to Windows message box
// without the button. CFlexMsgBox is derived from CFlexWnd.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __FLEXMsgBox_H__
#define __FLEXMsgBox_H__
class CFlexMsgBox : public CFlexWnd
{
LPTSTR m_tszText; // Text string of the message
COLORREF m_rgbText, m_rgbBk, m_rgbSelText, m_rgbSelBk, m_rgbFill, m_rgbLine;
HFONT m_hFont;
BOOL m_bSent;
HWND m_hWndNotify;
void SetRect();
void InternalPaint(HDC hDC);
RECT GetRect(const RECT &);
RECT GetRect();
void Notify(int code);
public:
CFlexMsgBox();
virtual ~CFlexMsgBox();
HWND Create(HWND hParent, const RECT &rect, BOOL bVisible);
void SetNotify(HWND hWnd) { m_hWndNotify = hWnd; }
void SetText(LPCTSTR tszText);
// cosmetics
void SetFont(HFONT hFont);
void SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line);
virtual void OnPaint(HDC hDC);
};
#endif

View File

@@ -0,0 +1,509 @@
//-----------------------------------------------------------------------------
// File: flexscrollbar.cpp
//
// Desc: Implements CFlexScrollBar (derived from CFlexWnd), a scroll bar
// control similar to a Windows scroll bar.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
CFlexScrollBar::CFlexScrollBar() :
m_nMin(0),
m_nMax(0),
m_nPage(25),
m_nPos(25),
m_bVert(TRUE),
m_hWndNotify(NULL),
m_bValid(FALSE),
m_bCapture(FALSE),
m_bDragging(FALSE),
m_code(SB_ENDSCROLL),
m_rgbBk(RGB(0,0,0)),
m_rgbFill(RGB(0,0,255)),
m_rgbLine(RGB(0,255,255))
{
}
CFlexScrollBar::~CFlexScrollBar()
{
}
CFlexScrollBar *CreateFlexScrollBar(FLEXSCROLLBARCREATESTRUCT *pcs)
{
CFlexScrollBar *psb = new CFlexScrollBar;
if (psb && psb->Create(pcs))
return psb;
delete psb;
return NULL;
}
BOOL CFlexScrollBar::Create(FLEXSCROLLBARCREATESTRUCT *pcs)
{
if (this == NULL)
return FALSE;
if (pcs == NULL)
return FALSE;
if (pcs->dwSize != sizeof(FLEXSCROLLBARCREATESTRUCT))
return FALSE;
if (pcs->min > pcs->max)
return FALSE;
int range = pcs->max - pcs->min;
if (pcs->page > range)
return FALSE;
m_bVert = ( pcs->dwFlags & FSBF_VERT ) == FSBF_VERT;
SetValues(pcs->min, pcs->max, pcs->page, pcs->pos);
m_hWndNotify = pcs->hWndNotify ? pcs->hWndNotify : pcs->hWndParent;
if (!CFlexWnd::Create(pcs->hWndParent, pcs->rect, pcs->bVisible))
return FALSE;
Calc();
// TODO: make sure that creation sends no notifications.
// all initial notifications should be sent here.
return TRUE;
}
int CFlexScrollBar::GetLineAdjust()
{
return 1;
}
int CFlexScrollBar::GetPageAdjust()
{
return m_nPage > 1 ? m_nPage - 1 : 1;
}
void CFlexScrollBar::AdjustPos(int adj, BOOL bForceCalc)
{
int old = m_nPos;
m_nPos += adj;
if (m_nPos < m_nMin)
m_nPos = m_nMin;
if (m_nPos > m_nMax - m_nPage)
m_nPos = m_nMax - m_nPage;
if (m_nPos == old && !bForceCalc)
return;
if (Calc())
Invalidate();
}
BOOL CFlexScrollBar::FailCalc(BOOL bOldValid)
{
m_bValid = FALSE;
if (bOldValid)
Invalidate();
return m_bValid;
}
BOOL CFlexScrollBar::Calc()
{
BOOL bOldValid = m_bValid;
#define FAIL return FailCalc(bOldValid)
if (!m_hWnd)
FAIL;
SRECT zero;
m_rectLineUp = zero;
m_rectPageUp = zero;
m_rectTrack = zero;
m_rectThumb = zero;
m_rectPageDown = zero;
m_rectLineDown = zero;
SPOINT size = GetClientSize();
int ord = m_bVert ? 1 : 0;
int nord = m_bVert ? 0 : 1;
int length = size.a[ord];
int width = size.a[nord];
int arrowlen = width;
if (width < 1 || length < 2)
FAIL;
int tracklen = length - arrowlen * 2;
int trackofs = arrowlen;
BOOL bOverlappingArrows = tracklen < -1;
int overlap = !bOverlappingArrows ? 0 : -tracklen;
SRECT up, down, track, thumb, temp;
if (overlap > 1)
{
int mid = length / 2;
up.lr.a[nord] = width;
up.lr.a[ord] = mid;
down.ul.a[ord] = mid;
down.lr.a[ord] = length;
down.lr.a[nord] = width;
m_rectLineUp = up;
m_rectLineDown = down;
return m_bValid = TRUE;
}
up.lr.a[nord] = width;
up.lr.a[ord] = arrowlen;
down.lr.a[nord] = width;
down.ul.a[ord] = length - arrowlen;
down.lr.a[ord] = length;
m_rectLineUp = up;
m_rectLineDown = down;
int tmin = up.lr.a[ord];
int tmax = down.ul.a[ord];
int trange = tmax - tmin;
int range = m_nMax - m_nMin;
assert(trange > 0);
if (!(range > 0) || !(trange > 0))
return m_bValid = TRUE;
track.ul.a[ord] = tmin;
track.lr.a[nord] = width;
track.lr.a[ord] = tmax;
m_rectTrack = track;
const int minthumblen = 3;
int thumblen = MulDiv(m_nPage, trange, range);
if (thumblen < minthumblen)
thumblen = minthumblen;
int thumbrange = trange - thumblen /*+ 1*/;
int pagerange = range - m_nPage;
if (!(pagerange > 1) || !(thumbrange > 1))
return m_bValid = TRUE;
int logpos = m_bDragging ? m_nPreDragPos : m_nPos;
int thumbpos = MulDiv(logpos - m_nMin, thumbrange, pagerange) + tmin;
if (m_bDragging)
{
SPOINT rp = m_point, rs = m_startpoint;
int rdelta = rp.a[ord] - rs.a[ord];
thumbpos += rdelta;
if (thumbpos < tmin)
thumbpos = tmin;
if (thumbpos > tmax - thumblen)
thumbpos = tmax - thumblen;
m_nThumbPos = MulDiv(thumbpos - tmin, pagerange, thumbrange) + m_nMin;
if (m_nThumbPos < m_nMin)
m_nThumbPos = m_nMin;
if (m_nThumbPos > m_nMax - m_nPage)
m_nThumbPos = m_nMax - m_nPage;
}
thumb.ul.a[ord] = thumbpos;
thumb.lr.a[nord] = width;
thumb.lr.a[ord] = thumbpos + thumblen;
m_rectThumb = thumb;
temp = track;
temp.lr.a[ord] = thumb.ul.a[ord];
if (temp.lr.a[ord] > temp.ul.a[ord])
m_rectPageUp = temp;
temp = track;
temp.ul.a[ord] = thumb.lr.a[ord];
if (temp.lr.a[ord] > temp.ul.a[ord])
m_rectPageDown = temp;
return m_bValid = TRUE;
#undef FAIL
}
void CFlexScrollBar::SetValues(int min, int max, int page, int pos)
{
m_nMin = min < max ? min : max;
m_nMax = max > min ? max : min;
m_nPage = page;
AdjustPos(pos - m_nPos, TRUE);
}
static BOOL UseRect(const RECT &rect)
{
if (rect.left >= rect.right || rect.bottom <= rect.top)
return FALSE;
return TRUE;
}
static void Rectangle(HDC hDC, RECT rect)
{
if (!UseRect(rect))
return;
Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
}
void CFlexScrollBar::OnPaint(HDC hDC)
{
HDC hBDC = NULL, hODC = NULL;
CBitmap *pbm = NULL;
if (!InRenderMode())
{
hODC = hDC;
pbm = CBitmap::Create(GetClientSize(), RGB(0,0,0), hDC);
if (pbm != NULL)
{
hBDC = pbm->BeginPaintInto();
if (hBDC != NULL)
{
hDC = hBDC;
}
}
}
InternalPaint(hDC);
if (!InRenderMode())
{
if (pbm != NULL)
{
if (hBDC != NULL)
{
pbm->EndPaintInto(hBDC);
pbm->Draw(hODC);
}
delete pbm;
}
}
}
void CFlexScrollBar::InternalPaint(HDC hDC)
{
HGDIOBJ hPen, hOldPen, hBrush, hOldBrush;
hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbBk);
if (hPen != NULL)
{
hOldPen = SelectObject(hDC, hPen),
hOldBrush = SelectObject(hDC, GetStockObject(BLACK_BRUSH));
Rectangle(hDC, m_rectPageUp);
Rectangle(hDC, m_rectPageDown);
Rectangle(hDC, m_rectLineUp);
Rectangle(hDC, m_rectLineDown);
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
hBrush = (HGDIOBJ)CreateSolidBrush(m_rgbFill);
if (hBrush != NULL)
{
SelectObject(hDC, (HGDIOBJ)hBrush);
hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbFill);
if (hPen != NULL)
{
SelectObject(hDC, hPen);
Rectangle(hDC, m_rectThumb);
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
}
hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbLine);
if (hPen != NULL)
{
SelectObject(hDC, hPen);
// draw the two arrows for this scrollbar
for (int i = 0; i < 2; i++)
DrawArrow(hDC, i ? m_rectLineUp : m_rectLineDown, m_bVert, i);
#if 0
// draw the two arrows for this scrollbar
for (int i = 0; i < 2; i++)
{
const RECT &rect = i == 0 ? m_rectLineUp : m_rectLineDown;
SRECT srect = rect;
srect.right--;
srect.bottom--;
int ord = m_bVert ? 1 : 0;
int nord = m_bVert ? 0 : 1;
SPOINT p(i ? srect.lr : srect.ul), b(i ? srect.ul : srect.lr);
b.a[ord] += 2 * i - 1;
SPOINT t = p;
t.a[nord] = (p.a[nord] + b.a[nord]) / 2;
SPOINT u;
u.a[ord] = b.a[ord];
u.a[nord] = p.a[nord];
POINT poly[] = { {t.x, t.y}, {u.x, u.y}, {b.x, b.y} };
Polygon(hDC, poly, 3);
}
#endif
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
}
SelectObject(hDC, hOldBrush);
DeleteObject(hBrush);
}
}
}
BOOL InRect(const RECT &rect, POINT point)
{
return UseRect(rect) && PtInRect(&rect, point);
}
LRESULT CFlexScrollBar::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_SIZE:
Calc();
Invalidate();
return 0;
// make sure flexwnd doesn't do ANYTHING with our mouse messages
case WM_MOUSEMOVE:
case WM_LBUTTONUP:
case WM_LBUTTONDOWN:
case WM_RBUTTONUP:
case WM_RBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
{
POINT point = {int(signed short(LOWORD(lParam))), int(signed short(HIWORD(lParam)))};
m_point = point;
m_code = HitTest(point);
}
case WM_TIMER:
case WM_CAPTURECHANGED:
break;
default:
return CFlexWnd::WndProc(hWnd, msg, wParam, lParam);
}
switch (msg)
{
case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
if (m_code == SB_ENDSCROLL)
goto endscroll;
if (m_code == SB_THUMBTRACK)
m_bDragging = TRUE;
else
SetTimer(m_hWnd, 1, 500, NULL);
m_startcode = m_code;
m_startpoint = m_point;
m_nPreDragPos = m_nPos;
m_bCapture = TRUE;
SetCapture();
if (!m_bDragging)
Notify(m_code);
break;
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
if (!m_bDragging)
break;
if (Calc())
{
Invalidate();
// Force repaint the updated scrollbar position. If we don't do this,
// the WM_PAINT message will be pre-empted by the WM_FLEXVSCROLL messages.
// Sometimes this happens during the entire duration of draggin the scroll
// bar. The result is that the scroll bar does not get updated when
// dragging.
SendMessage(m_hWnd, WM_PAINT, 0, 0);
}
Notify(m_startcode);
break;
case WM_TIMER:
if (m_bCapture) switch (wParam)
{
case 1:
KillTimer(m_hWnd, 1);
SetTimer(m_hWnd, 2, 50, NULL);
case 2:
if (m_bDragging)
break;
if (m_code == m_startcode)
Notify(m_code);
break;
}
break;
}
switch (msg)
{
case WM_LBUTTONUP:
case WM_CAPTURECHANGED:
endscroll:
if (m_bCapture)
{
m_bCapture = FALSE;
KillTimer(m_hWnd, 1);
KillTimer(m_hWnd, 2);
ReleaseCapture();
if (m_bDragging)
Notify(SB_THUMBPOSITION);
BOOL bWasDragging = m_bDragging;
m_bDragging = FALSE;
if (bWasDragging)
{
if (Calc())
Invalidate();
}
Notify(SB_ENDSCROLL);
}
break;
}
return 0;
}
void CFlexScrollBar::Notify(int code)
{
if (!m_hWndNotify)
return;
SendMessage(m_hWndNotify, m_bVert ? WM_FLEXVSCROLL : WM_FLEXHSCROLL,
(WPARAM)code, (LPARAM)(LPVOID)this);
}
int CFlexScrollBar::HitTest(POINT point)
{
if (InRect(m_rectLineUp, point))
return SB_LINEUP;
else if (InRect(m_rectLineDown, point))
return SB_LINEDOWN;
else if (InRect(m_rectThumb, point))
return SB_THUMBTRACK;
else if (InRect(m_rectPageUp, point))
return SB_PAGEUP;
else if (InRect(m_rectPageDown, point))
return SB_PAGEDOWN;
else
return SB_ENDSCROLL;
}
void CFlexScrollBar::SetColors(COLORREF bk, COLORREF fill, COLORREF line)
{
m_rgbBk = bk;
m_rgbFill = fill;
m_rgbLine = line;
Invalidate();
}

View File

@@ -0,0 +1,105 @@
//-----------------------------------------------------------------------------
// File: flexscrollbar.h
//
// Desc: Implements CFlexScrollBar (derived from CFlexWnd), a scroll bar
// control similar to a Windows scroll bar.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __FLEXSCROLLBAR_H__
#define __FLEXSCROLLBAR_H__
#include "flexwnd.h"
#define FSBF_HORZ 0
#define FSBF_VERT 1
struct FLEXSCROLLBARCREATESTRUCT {
DWORD dwSize;
DWORD dwFlags;
int min, max, page, pos;
HWND hWndParent;
HWND hWndNotify;
RECT rect;
BOOL bVisible;
};
class CFlexScrollBar : public CFlexWnd
{
public:
CFlexScrollBar();
~CFlexScrollBar();
BOOL Create(FLEXSCROLLBARCREATESTRUCT *);
void SetColors(COLORREF bk, COLORREF fill, COLORREF line);
void SetValues(int, int, int, int);
void SetValues(int min, int max, int page) {SetRange(min, max, page);}
void SetValues(int min, int max) {SetRange(min, max);}
void SetRange(int min, int max, int page) {SetValues(min, max, page, GetPos());}
void SetRange(int min, int max) {SetRange(min, max, GetPage());}
void SetMin(int v) {SetValues(v, GetMax(), GetPage(), GetPos());}
void SetMax(int v) {SetValues(GetMin(), v, GetPage(), GetPos());}
void SetPage(int v) {SetValues(GetMin(), GetMax(), v, GetPos());}
void SetPos(int v) {SetValues(GetMin(), GetMax(), GetPage(), v);}
int GetMin() {return m_nMin;}
int GetMax() {return m_nMax;}
int GetPage() {return m_nPage;}
int GetPos() {return m_nPos;}
int GetThumbPos() {return m_bDragging ? m_nThumbPos : -1;}
void AdjustPos(int adj, BOOL bForceCalc = FALSE);
protected:
virtual void OnPaint(HDC hDC);
virtual LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
int m_nMin, m_nMax, m_nPage, m_nPos;
BOOL m_bVert;
HWND m_hWndNotify;
COLORREF m_rgbBk, m_rgbFill, m_rgbLine;
// ui rects... calced by Calc
RECT m_rectLineUp;
RECT m_rectPageUp;
RECT m_rectTrack;
RECT m_rectThumb;
RECT m_rectPageDown;
RECT m_rectLineDown;
BOOL Calc();
BOOL FailCalc(BOOL);
BOOL m_bValid; // true only when we have been created and hav valid values
// and calc has been called and returned successfully.
void InternalPaint(HDC hDC);
POINT m_point, m_startpoint;
int m_nThumbPos, m_nPreDragPos;
int m_code;
int m_startcode;
BOOL m_bCapture;
BOOL m_bDragging;
int HitTest(POINT point);
void Notify(int code);
int GetLineAdjust();
int GetPageAdjust();
};
CFlexScrollBar *CreateFlexScrollBar(FLEXSCROLLBARCREATESTRUCT *pcs);
#endif //__FLEXSCROLLBAR_H__

View File

@@ -0,0 +1,218 @@
//-----------------------------------------------------------------------------
// File: flextooltip.cpp
//
// Desc: Implements a tooltip class that displays a text string as a tooltip.
// CFlexTooltip (derived from CFlexWnd) is used throughout the UI when
// a control needs to have a tooltip.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
UINT_PTR CFlexToolTip::s_uiTimerID;
DWORD CFlexToolTip::s_dwLastTimeStamp; // Last time stamp for mouse move
TOOLTIPINIT CFlexToolTip::s_TTParam; // Parameters to initialize the tooltip
// TimerFunc is called periodically. It checks if a tooltip should be displayed.
// If a window has indicated a need for tooltip, TimerFunc will initialize
// for displaying here. CFlexWnd will do the actual displaying, since
// it has to monitor WM_MOUSEMOVE message to be sure that tooltips only
// display after a period of inactivity.
void CALLBACK CFlexToolTip::TimerFunc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
// If it has been one sec already since last mouse move, display the tooltip
if (dwTime > CFlexWnd::s_dwLastMouseMove + 1000)
{
if (s_TTParam.hWndParent && !CFlexWnd::s_ToolTip.IsEnabled())
{
// Check if the mouse cursor is outside the window. If so, don't activate tooltip.
POINT pt;
RECT rect;
GetCursorPos(&pt);
ScreenToClient(s_TTParam.hWndParent, &pt);
::GetClientRect(s_TTParam.hWndParent, &rect);
if (!PtInRect(&rect, pt))
return;
SetParent(CFlexWnd::s_ToolTip.m_hWnd, s_TTParam.hWndParent);
CFlexWnd::s_ToolTip.SetSBWidth(s_TTParam.iSBWidth);
CFlexWnd::s_ToolTip.SetID(s_TTParam.dwID);
CFlexWnd::s_ToolTip.SetNotifyWindow(s_TTParam.hWndNotify);
CFlexWnd::s_ToolTip.SetText(s_TTParam.tszCaption);
CFlexWnd::s_ToolTip.SetEnable(TRUE);
}
}
}
// We use the constructor and destructor to load and unload WINMM.DLL since the UI will only create this once.
CFlexToolTip::CFlexToolTip() :
m_tszText(NULL), m_hNotifyWnd(NULL), m_dwID(0), m_bEnabled(FALSE)
{
}
CFlexToolTip::~CFlexToolTip()
{
delete[] m_tszText;
}
HWND CFlexToolTip::Create(HWND hParent, const RECT &rect, BOOL bVisible, int iSBWidth)
{
m_iSBWidth = iSBWidth;
return CFlexWnd::Create(hParent, rect, bVisible);
}
// Set the tooltip position. pt is the upper-left point in screen coordinates.
// bOffsetForMouseCursor is TRUE if the tooltip is to be displayed next to mouse cursor. SetPosition()
// will offset the position of the tooltip so that the cursor doesn't block the text of the tooltip.
void CFlexToolTip::SetPosition(POINT pt, BOOL bOffsetForMouseCursor)
{
// Check the top, right and bottom edges. If they are outside the main config window
RECT rc;
RECT cliprc;
RECT parentrc;
GetWindowRect(GetParent(), &parentrc);
GetClientRect(&rc);
GetWindowRect(GetParent(), &cliprc);
cliprc.right -= DEFAULTVIEWSBWIDTH*2;
if (bOffsetForMouseCursor)
{
pt.y -= rc.bottom; // Align the lower left corner to the cursor
pt.x += 1; pt.y -= 1; // Offset x and y by 2 pixels so that when the mouse is moved up or right, we don't get over the tooltip window.
}
if (pt.y < cliprc.top) pt.y += cliprc.top - pt.y; // Top
if (pt.x + rc.right > (cliprc.right - m_iSBWidth)) pt.x += cliprc.right - m_iSBWidth - (pt.x + rc.right); // Right
if (pt.y + rc.bottom > cliprc.bottom) pt.y += cliprc.bottom - (pt.y + rc.bottom); // Bottom
ScreenToClient(GetParent(), &pt);
SetWindowPos(m_hWnd, HWND_TOP, pt.x, pt.y, 0, 0, SWP_NOSIZE);
}
void CFlexToolTip::SetText(LPCTSTR tszText, POINT *textpos)
{
// Figure out window size and position
RECT rc = {0, 0, 320, 480}; // Only go to half the window width max
HDC hDC = CreateCompatibleDC(NULL);
if (hDC != NULL)
{
DrawText(hDC, CFlexToolTip::s_TTParam.tszCaption, -1, &rc, DT_CALCRECT);
// DrawText(hDC, m_tszText, -1, &rc, DT_CALCRECT);
SetWindowPos(m_hWnd, HWND_TOP, 0, 0, rc.right, rc.bottom, 0); // Set window pos as needed by text
DeleteDC(hDC);
}
POINT pt;
if (textpos)
{
pt = *textpos;
SetPosition(pt, FALSE);
}
else
{
GetCursorPos(&pt);
SetPosition(pt);
}
SetWindowPos(m_hWnd, HWND_TOP, 0, 0, rc.right, rc.bottom, SWP_NOMOVE); // Set size
}
void CFlexToolTip::OnClick(POINT point, WPARAM fwKeys, BOOL bLeft)
{
ClientToScreen(m_hWnd, &point);
ScreenToClient(m_hNotifyWnd, &point);
if (bLeft)
PostMessage(m_hNotifyWnd, WM_LBUTTONDOWN, fwKeys, point.x | (point.y << 16));
else
PostMessage(m_hNotifyWnd, WM_RBUTTONDOWN, fwKeys, point.x | (point.y << 16));
}
void CFlexToolTip::OnDoubleClick(POINT point, WPARAM fwKeys, BOOL bLeft)
{
ClientToScreen(m_hWnd, &point);
ScreenToClient(m_hNotifyWnd, &point);
if (bLeft)
PostMessage(m_hNotifyWnd, WM_LBUTTONDBLCLK, fwKeys, point.x | (point.y << 16));
else
PostMessage(m_hNotifyWnd, WM_RBUTTONDBLCLK, fwKeys, point.x | (point.y << 16));
}
void CFlexToolTip::OnPaint(HDC hDC)
{
HDC hBDC = NULL, hODC = NULL;
CBitmap *pbm = NULL;
if (!InRenderMode())
{
hODC = hDC;
pbm = CBitmap::Create(GetClientSize(), RGB(0,0,0), hDC);
if (pbm != NULL)
{
hBDC = pbm->BeginPaintInto();
if (hBDC != NULL)
{
hDC = hBDC;
}
}
}
InternalPaint(hDC);
if (!InRenderMode())
{
if (pbm != NULL)
{
if (hBDC != NULL)
{
pbm->EndPaintInto(hBDC);
pbm->Draw(hODC);
}
delete pbm;
}
}
}
void CFlexToolTip::InternalPaint(HDC hDC)
{
HGDIOBJ hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbBk);
if (hPen != NULL)
{
HGDIOBJ hOldPen = SelectObject(hDC, hPen);
HGDIOBJ hBrush = CreateSolidBrush(m_rgbBk);
if (hBrush != NULL)
{
HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
RECT rc = {0,0,0,0};
GetClientRect(&rc);
DrawText(hDC, CFlexToolTip::s_TTParam.tszCaption, -1, &rc, DT_LEFT);
SelectObject(hDC, hOldBrush);
DeleteObject(hBrush);
}
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
}
}
LRESULT CFlexToolTip::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
return CFlexWnd::WndProc(hWnd, msg, wParam, lParam);
}
LRESULT CFlexToolTip::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
// Create a timer
CFlexToolTip::s_uiTimerID = SetTimer(m_hWnd, 6, 50, CFlexToolTip::TimerFunc);
return 0;
}
void CFlexToolTip::OnDestroy()
{
// Kill the timer
if (CFlexToolTip::s_uiTimerID)
{
KillTimer(m_hWnd, 6);
CFlexToolTip::s_uiTimerID = 0;
}
}

View File

@@ -0,0 +1,110 @@
//-----------------------------------------------------------------------------
// File: flextooltip.h
//
// Desc: Implements a tooltip class that displays a text string as a tooltip.
// CFlexTooltip (derived from CFlexWnd) is used throughout the UI when
// a control needs to have a tooltip.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __FLEXTOOLTIP_H__
#define __FLEXTOOLTIP_H__
struct TOOLTIPINIT
{
HWND hWndParent;
int iSBWidth;
DWORD dwID;
HWND hWndNotify;
TCHAR tszCaption[MAX_PATH];
};
struct TOOLTIPINITPARAM
{
HWND hWndParent;
int iSBWidth;
DWORD dwID;
HWND hWndNotify;
LPCTSTR tszCaption;
};
class CFlexToolTip : public CFlexWnd
{
LPTSTR m_tszText;
COLORREF m_rgbText, m_rgbBk, m_rgbSelText, m_rgbSelBk, m_rgbFill, m_rgbLine;
HWND m_hNotifyWnd;
DWORD m_dwID; // Used to store offset when owned by a control
int m_iSBWidth; // Width of the owner window's scroll bar. We cannot obscure the scroll bar.
BOOL m_bEnabled; // Whether this is enabled. If not, we hide the underlying window.
void InternalPaint(HDC hDC);
public:
CFlexToolTip();
virtual ~CFlexToolTip();
// Statics for show control
static UINT_PTR s_uiTimerID;
static DWORD s_dwLastTimeStamp; // Last time stamp for mouse move
static TOOLTIPINIT s_TTParam; // Parameters to initialize the tooltip
static void SetToolTipParent(HWND hWnd) { s_TTParam.hWndParent = hWnd; }
static void UpdateToolTipParam(TOOLTIPINITPARAM &TTParam)
{
s_TTParam.hWndParent = TTParam.hWndParent;
s_TTParam.iSBWidth = TTParam.iSBWidth;
s_TTParam.dwID = TTParam.dwID;
s_TTParam.hWndNotify = TTParam.hWndNotify;
if (TTParam.tszCaption)
lstrcpy((LPTSTR)s_TTParam.tszCaption, TTParam.tszCaption);
else
s_TTParam.tszCaption[0] = _T('\0');
}
static TOOLTIPINIT &GetTTParam() { return s_TTParam; }
static void CALLBACK TimerFunc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
HWND Create(HWND hParent, const RECT &rect, BOOL bVisible, int iSBWidth = 0);
HWND GetParent() { return ::GetParent(m_hWnd); }
virtual LRESULT OnCreate(LPCREATESTRUCT lpCreateStruct);
virtual void OnDestroy();
private:
void SetNotifyWindow(HWND hWnd) { m_hNotifyWnd = hWnd; }
void SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line);
void SetText(LPCTSTR tszText, POINT *textpos = NULL);
void SetID(DWORD dwID) { m_dwID = dwID; }
void SetPosition(POINT pt, BOOL bOffsetForMouseCursor = TRUE);
void SetSBWidth(int iSBWidth) { m_iSBWidth = iSBWidth; }
public:
DWORD GetID() { return m_dwID; }
void SetEnable(BOOL bEnable)
{
if (m_hWnd)
{
if (bEnable && !m_bEnabled)
{
ShowWindow(m_hWnd, SW_SHOW);
Invalidate();
}
else if (!bEnable && m_bEnabled)
{
ShowWindow(m_hWnd, SW_HIDE);
Invalidate();
}
}
m_bEnabled = bEnable;
}
BOOL IsEnabled() { return m_bEnabled; }
virtual void OnClick(POINT point, WPARAM fwKeys, BOOL bLeft);
virtual void OnDoubleClick(POINT point, WPARAM fwKeys, BOOL bLeft);
protected:
virtual void OnPaint(HDC hDC);
virtual LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,297 @@
//-----------------------------------------------------------------------------
// File: flextree.h
//
// Desc: Implements a tree class, similar to a Windows tree control,
// based on CFlexWnd. It is used by the page to display the action
// list when the user wishes to assign an action to a control.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __FLEXTREE_H__
#define __FLEXTREE_H__
#include "flexscrollbar.h"
class CFTItem;
class CFlexTree;
typedef struct {
CFlexTree *pTree;
CFTItem *pItem, *pOldItem;
POINT point;
HDC hDC;
WPARAM fwKeys;
BOOL bLeft;
} FLEXTREENOTIFY;
enum {
FTN_CLICK,
FTN_OWNERDRAW,
FTN_SELCHANGED,
FTN_MOUSEOVER
};
enum {
CLMF_NONE = 0x00000000,
CLMF_TEXTCOLOR = 0x00000001,
CLMF_BKCOLOR = 0x00000002,
CLMF_BKMODE = 0x00000004,
CLMF_BKEXTENDS = 0x00000008,
CLMF_FONT = 0x00000010,
CLMF_LINECOLOR = 0x00000020,
CLMF_ALL = 0x0000003f
};
struct _CAPTIONLOOK;
typedef struct _CAPTIONLOOK {
_CAPTIONLOOK() : dwSize(sizeof(_CAPTIONLOOK)), dwMask(CLMF_NONE),
rgbTextColor(RGB(0,0,0)), rgbBkColor(RGB(255,255,255)), rgbLineColor(RGB(255,0,0)), nBkMode(TRANSPARENT),
bBkExtends(FALSE), hFont(NULL) {}
DWORD dwSize;
DWORD dwMask;
COLORREF rgbTextColor, rgbBkColor, rgbLineColor, nBkMode;
BOOL bBkExtends;
HFONT hFont;
} CAPTIONLOOK;
typedef enum {
ATTACH_FIRSTCHILD,
ATTACH_LASTCHILD,
ATTACH_FIRSTSIBLING,
ATTACH_LASTSIBLING,
ATTACH_BEFORE,
ATTACH_AFTER
} ATTACHREL;
class CFlexTree : public CFlexWnd
{
friend class CFTItem;
public:
CFlexTree();
~CFlexTree();
// creation
BOOL Create(HWND hParent, const RECT &, BOOL bVisible = TRUE, BOOL bOwnerDraw = FALSE);
// look
void SetScrollBarColors(COLORREF bk, COLORREF fill, COLORREF line);
void SetDefCaptionLook(const CAPTIONLOOK &, BOOL bSel = FALSE);
void GetDefCaptionLook(CAPTIONLOOK &, BOOL bSel = FALSE) const;
void SetDefMargin(const RECT &);
void GetDefMargin(RECT &) const;
void SetRootChildIndent(int);
int GetRootChildIndent() const;
void SetDefChildIndent(int);
int GetDefChildIndent() const;
void SetBkColor(COLORREF);
COLORREF GetBkColor() const;
// adding default type items
CFTItem *DefAddItem(LPCTSTR tszCaption, CFTItem *to, ATTACHREL rel = ATTACH_AFTER);
CFTItem *DefAddItem(LPCTSTR tszCaption, ATTACHREL rel = ATTACH_AFTER);
// freeing
void FreeAll();
// root access
operator CFTItem *() const {return m_pRoot;}
CFTItem *GetRoot() const {return m_pRoot;}
// access
CFTItem *GetFirstItem() const;
CFTItem *GetLastItem() const;
CFTItem *GetFirstVisibleItem() const;
CFTItem *GetItemFromPoint(POINT point) const;
// selection
void SetCurSel(CFTItem *);
CFTItem *GetCurSel() const;
// finding
CFTItem *FindItem(const GUID &guid, void *pUserData) const;
CFTItem *FindItemEx(const GUID &guid, DWORD dwFindType, void *pVoid) const;
protected:
virtual BOOL OnEraseBkgnd(HDC hDC) {return TRUE;}
virtual void OnPaint(HDC hDC);
virtual void OnMouseOver(POINT point, WPARAM fwKeys);
virtual void OnClick(POINT point, WPARAM fwKeys, BOOL bLeft);
virtual void OnWheel(POINT point, WPARAM wParam);
virtual LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
// event notification firing
void FireClick(CFTItem *pItem, POINT point, WPARAM fwKeys, BOOL bLeft);
BOOL FireOwnerDraw(CFTItem *pItem, HDC hDC);
void FireSelChanged(CFTItem *pItem, CFTItem *pOld);
private:
CFTItem *m_pRoot; // root item
CFTItem *m_pCurSel; // selected item
CFTItem *m_pLastAdded;
BOOL m_bOwnerDraw;
POINT m_ptScrollOrigin;
COLORREF m_rgbBkColor;
CAPTIONLOOK m_clDefNormal, m_clDefSelected;
RECT m_defmargin;
int m_nDefChildIndent;
// scrolling
int m_nVertSBWidth;
int m_nHorzSBHeight;
BOOL m_bVertSB, m_bHorzSB;
CFlexScrollBar m_VertSB, m_HorzSB;
int m_nTotalWidth;
// helpers
BOOL m_bNeedPaintBkgnd;
void SetDirty();
void InternalPaint(HDC hDC);
BOOL m_bDirty;
void Calc();
void CalcItems();
BOOL IsMine(CFTItem *pItem);
void LosePointer(CFTItem *pItem);
};
class CFTItem
{
friend class CFlexTree;
public:
CFTItem();
~CFTItem();
// operations
BOOL IsOut() const;
BOOL IsExpanded() const {return m_bExpanded;}
void Expand(BOOL bAll = FALSE);
void ExpandAll() {Expand(TRUE);}
void Collapse(BOOL bAll = FALSE);
void CollapseAll() {Collapse(TRUE);}
void EnsureVisible();
void Invalidate();
// caption
void SetCaptionLook(const CAPTIONLOOK &, BOOL bSel = FALSE);
void GetCaptionLook(CAPTIONLOOK &, BOOL bSel = FALSE) const;
void SetCaption(LPCTSTR);
LPCTSTR GetCaption() const;
BOOL HasCaption() const {return GetCaption() != NULL;}
void SetMargin(const RECT &);
void GetMargin(RECT &) const;
// attach/detachment
void Detach(); // detaches this leaf/branch from parent. (does not affect children, who may still be attached to this)
void FreeChildren(); // detach and free each child (which in turn frees all their's, etc.)
BOOL Attach(CFTItem *to, ATTACHREL rel);
BOOL Attach(CFTItem &to, ATTACHREL rel) {return Attach(&to, rel);}
BOOL IsOnTree() const;
BOOL IsAttached() const;
BOOL IsAlone() const;
// family access
CFlexTree *GetTree() const {return m_pTree;}
CFTItem *GetParent() const {return m_pParent;}
CFTItem *GetPrevSibling() const {return m_pPrev;}
CFTItem *GetNextSibling() const {return m_pNext;}
CFTItem *GetFirstChild() const {return m_pFirst;}
CFTItem *GetLastChild() const {return m_pLast;}
CFTItem *GetNextOut() const;
CFTItem *GetNext(BOOL bOutOnly = FALSE) const;
BOOL HasChildren() const {return m_pFirst != NULL;}
// dimension access
void GetItemRect(RECT &) const;
void GetBranchRect(RECT &) const;
// user guid/data operations
BOOL IsUserGUID(const GUID &check) const {return IsEqualGUID(m_UserGUID, check);}
void SetUserGUID(const GUID &set) {m_UserGUID = set;}
const GUID &GetUserGUID() const {return m_UserGUID;}
void SetUserData(void *p) {m_pUserData = p;}
void *GetUserData() const {return m_pUserData;}
// selection
BOOL IsSelected() const;
// owner draw
void PaintInto(HDC hDC);
protected:
// internal/derived-customization operations
void SetWidth(int);
int GetWidth() const {return m_nWidth;}
void SetHeight(int);
int GetHeight() const {return m_nHeight;}
void SetIndent(int);
int GetIndent() const {return m_nIndent;}
void SetChildIndent(int);
int GetChildIndent() const {return m_nChildIndent;}
// customization
virtual void OnPaint(HDC hDC);
virtual void OnMouseOver(POINT point, WPARAM fwKeys) {}
virtual void OnClick(POINT point, WPARAM fwKeys, BOOL bLeft);
// expansion customization
public: virtual BOOL IsExpandable() {return GetFirstChild() != NULL;}
protected:
virtual void OnExpand() {}
virtual void OnCollapse() {}
// finding
virtual BOOL FoundItem(DWORD dwUser, void *pUser) const {return FALSE;}
// event notification firing
void FireClick(POINT point, WPARAM fwKeys, BOOL bLeft);
BOOL FireOwnerDraw(HDC hDC);
private:
// caption
LPTSTR m_ptszCaption;
CAPTIONLOOK m_clNormal, m_clSelected;
RECT m_margin;
// user data
GUID m_UserGUID;
void *m_pUserData;
// raw characteristics
int m_nWidth; // item's width (used only to provide horizontal scrolling as necessary)
int m_nHeight; // item's height (not including children)
int m_nIndent; // indent of this item relative to parent's child indent origin (full origin = this + parent origin + parent child indent)
int m_nChildIndent; // indentation of this item's children (relative to this's origin)
// calced characteristics
int m_nBranchHeight; // height of item and all currently expanded children
// calced positioning
POINT m_origin; // relative to ideal tree origin
// state
BOOL m_bExpanded; // is branch expanded/children shown?
// family
CFlexTree *m_pTree;
CFTItem *m_pParent, *m_pPrev, *m_pNext, *m_pFirst, *m_pLast;
// root
BOOL IsRoot() const;
void SetRoot(CFlexTree *);
// helpers
void SetTree(CFlexTree *);
BOOL Attach(CFTItem *pParent, CFTItem *pPrev, CFTItem *pNext);
void SetTreeDirty(CFlexTree *pTree = NULL);
void RecalcText();
void Init();
void SelChangedInternal();
void InternalExpand(BOOL bExpand, BOOL bAll);
};
#endif //__FLEXTREE_H__

View File

@@ -0,0 +1,621 @@
//-----------------------------------------------------------------------------
// File: flexwnd.cpp
//
// Desc: CFlexWnd is a generic class that encapsulates the functionalities
// of a window. All other window classes are derived from CFlexWnd.
//
// Child classes can have different behavior by overriding the
// overridable message handlers (OnXXX members).
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
#include "typeinfo.h"
BOOL CFlexWnd::sm_bWndClassRegistered = FALSE;
WNDCLASSEX CFlexWnd::sm_WndClass;
LPCTSTR CFlexWnd::sm_tszWndClassName = _T("Microsoft.CFlexWnd.WndClassName");
HINSTANCE CFlexWnd::sm_hInstance = NULL;
CFlexToolTip CFlexWnd::s_ToolTip; // Shared tooltip window object
DWORD CFlexWnd::s_dwLastMouseMove; // Last GetTickCount() that we have a WM_MOUSEMOVE
HWND CFlexWnd::s_hWndLastMouseMove; // Last window handle of WM_MOUSEMOVE
LPARAM CFlexWnd::s_PointLastMouseMove; // Last point of WM_MOUSEMOVE
HWND CFlexWnd::s_CurrPageHwnd; // For unhighlighting callouts when a click is made outside of a callout
int NewID()
{
static int i = 0;
return ++i;
}
CFlexWnd::CFlexWnd() : m_nID(NewID()),
m_hWnd(m_privhWnd), m_privhWnd(NULL), m_hRenderInto(NULL),
m_bIsDialog(FALSE), m_bRender(FALSE),
m_bReadOnly(FALSE)
{
}
CFlexWnd::~CFlexWnd()
{
Destroy();
}
void CFlexWnd::Destroy()
{
if (m_hWnd != NULL)
DestroyWindow(m_hWnd);
assert(m_privhWnd == NULL);
}
BOOL CFlexWnd::IsDialog()
{
return HasWnd() && m_bIsDialog;
}
void CFlexWnd::OnRender(BOOL bInternalCall)
{
// if parent is flexwnd and both are in render mode, pass to parent
if (!m_hWnd)
return;
HWND hParent = GetParent(m_hWnd);
if (!hParent)
return;
CFlexWnd *pParent = GetFlexWnd(hParent);
if (!pParent)
return;
if (pParent->InRenderMode() && InRenderMode())
pParent->OnRender(TRUE);
}
BOOL CFlexWnd::OnEraseBkgnd(HDC hDC)
{
if (InRenderMode())
return TRUE;
/* if (IsDialog())
return FALSE;*/
return TRUE;
}
struct GETFLEXWNDSTRUCT {
int cbSize;
BOOL bFlexWnd;
CFlexWnd *pFlexWnd;
};
// This function takes a HWND and returns a pointer to CFlexWnd if the HWND is a window
// created by the UI.
CFlexWnd *CFlexWnd::GetFlexWnd(HWND hWnd)
{
if (hWnd == NULL)
return NULL;
GETFLEXWNDSTRUCT gfws;
gfws.cbSize = sizeof(gfws);
gfws.bFlexWnd = FALSE;
gfws.pFlexWnd = NULL;
SendMessage(hWnd, WM_GETFLEXWND, 0, (LPARAM)(LPVOID)(FAR GETFLEXWNDSTRUCT *)&gfws);
if (gfws.bFlexWnd)
return gfws.pFlexWnd;
else
return NULL;
}
// Basic window proc. It simply forward interesting messages to the appropriate handlers (OnXXX).
// If child class defines this function, it should pass unhandled messages to CFlexWnd.
LRESULT CFlexWnd::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_GETFLEXWND:
{
if ((LPVOID)lParam == NULL)
break;
GETFLEXWNDSTRUCT &gfws = *((FAR GETFLEXWNDSTRUCT *)(LPVOID)lParam);
switch (gfws.cbSize)
{
case sizeof(GETFLEXWNDSTRUCT):
gfws.bFlexWnd = TRUE;
gfws.pFlexWnd = this;
return 0;
default:
assert(0);
break;
}
break;
}
case WM_CREATE:
{
LPCREATESTRUCT lpCreateStruct = (LPCREATESTRUCT)lParam;
LRESULT lr = OnCreate(lpCreateStruct);
if (lr != -1)
OnInit();
return lr;
}
case WM_INITDIALOG:
{
BOOL b = OnInitDialog();
OnInit();
return b;
}
case WM_TIMER:
OnTimer((UINT)wParam);
return 0;
case WM_ERASEBKGND:
return OnEraseBkgnd((HDC)wParam);
case WM_PAINT:
{
// Check the update rectangle. If we don't have it, exit immediately.
if (typeid(*this) == typeid(CDeviceView) && !GetUpdateRect(m_hWnd, NULL, FALSE))
return 0;
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
if (InRenderMode())
OnRender(TRUE);
else
DoOnPaint(hDC);
EndPaint(hWnd, &ps);
return 0;
}
case WM_COMMAND:
{
WORD wNotifyCode = HIWORD(wParam);
WORD wID = LOWORD(wParam);
HWND hWnd = (HWND)lParam;
return OnCommand(wNotifyCode, wID, hWnd);
}
case WM_NOTIFY:
return OnNotify(wParam, lParam);
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_MOUSEWHEEL:
{
POINT point = {int(LOWORD(lParam)), int(HIWORD(lParam))};
switch (msg)
{
case WM_MOUSEMOVE: OnMouseOver(point, wParam); break;
case WM_LBUTTONDOWN: OnClick(point, wParam, TRUE); break;
case WM_RBUTTONDOWN: OnClick(point, wParam, FALSE); break;
case WM_LBUTTONDBLCLK: OnDoubleClick(point, wParam, TRUE); break;
case WM_MOUSEWHEEL:
{
// Send wheel msg to the window beneath the cursor
HWND hWnd = WindowFromPoint(point);
CFlexWnd *pWnd = NULL;
if (hWnd)
{
pWnd = GetFlexWnd(hWnd);
if (pWnd)
pWnd->OnWheel(point, wParam);
else
return DefWindowProc(hWnd, msg, wParam, lParam);
}
break;
}
}
return 0;
}
case WM_DESTROY:
OnDestroy();
m_privhWnd = NULL;
return 0;
}
if (!m_bIsDialog)
return DefWindowProc(hWnd, msg, wParam, lParam);
else
return 0;
}
static HMENU windex = 0;
BOOL CFlexWnd::EndDialog(int n)
{
if (!m_bIsDialog || m_hWnd == NULL)
{
assert(0);
return FALSE;
}
return ::EndDialog(m_hWnd, n);
}
int CFlexWnd::DoModal(HWND hParent, int nTemplate, HINSTANCE hInst)
{
return DoModal(hParent, MAKEINTRESOURCE(nTemplate), hInst);
}
HWND CFlexWnd::DoModeless(HWND hParent, int nTemplate, HINSTANCE hInst)
{
return DoModeless(hParent, MAKEINTRESOURCE(nTemplate), hInst);
}
int CFlexWnd::DoModal(HWND hParent, LPCTSTR lpTemplate, HINSTANCE hInst)
{
if (m_hWnd != NULL)
{
assert(0);
return -1;
}
if (hInst == NULL)
hInst = CFlexWnd::sm_hInstance;
return (int)DialogBoxParam(hInst, lpTemplate, hParent,
(DLGPROC)__BaseFlexWndDialogProc, (LPARAM)(void *)this);
}
HWND CFlexWnd::DoModeless(HWND hParent, LPCTSTR lpTemplate, HINSTANCE hInst)
{
if (m_hWnd != NULL)
{
assert(0);
return NULL;
}
if (hInst == NULL)
hInst = CFlexWnd::sm_hInstance;
return CreateDialogParam(hInst, lpTemplate, hParent,
(DLGPROC)__BaseFlexWndDialogProc, (LPARAM)(void *)this);
}
HWND CFlexWnd::Create(HWND hParent, const RECT &rect, BOOL bVisible)
{
++(*(LPBYTE*)&windex);
return Create(hParent, _T("(unnamed)"), 0,
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_EX_NOPARENTNOTIFY | (bVisible ? WS_VISIBLE : 0),
rect, windex);
}
HWND CFlexWnd::Create(HWND hParent, LPCTSTR tszName, DWORD dwExStyle, DWORD dwStyle, const RECT &rect, HMENU hMenu)
{
HWND hWnd = NULL;
if (m_hWnd != NULL)
{
assert(0);
return hWnd;
}
if (hMenu == NULL && (dwStyle & WS_CHILD))
{
++(*(LPBYTE*)&windex);
hMenu = windex;
}
hWnd = CreateWindowEx(
dwExStyle,
CFlexWnd::sm_tszWndClassName,
tszName,
dwStyle,
rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
hParent,
hMenu,
CFlexWnd::sm_hInstance,
(void *)this);
assert(m_hWnd == hWnd);
return hWnd;
}
void CFlexWnd::SetHWND(HWND hWnd)
{
assert(m_hWnd == NULL && hWnd != NULL);
m_privhWnd = hWnd;
assert(m_hWnd == m_privhWnd);
InitFlexWnd();
}
void CFlexWnd::InitFlexWnd()
{
if (!HasWnd())
return;
HWND hParent = GetParent(m_hWnd);
CFlexWnd *pParent = GetFlexWnd(hParent);
if (pParent && pParent->InRenderMode())
SetRenderMode();
}
TCHAR sg_tszFlexWndPointerProp[] = _T("CFlexWnd *");
LRESULT CALLBACK __BaseFlexWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
CFlexWnd *pThis = (CFlexWnd *)GetProp(hWnd, sg_tszFlexWndPointerProp);
if ((msg == WM_MOUSEMOVE || msg == WM_MOUSEWHEEL) && hWnd != CFlexWnd::s_ToolTip.m_hWnd)
{
// Filter out the message with same window handle and point.
// Windows sometimes seems to send us WM_MOUSEMOVE message even though the mouse is not moved.
if (CFlexWnd::s_hWndLastMouseMove != hWnd || CFlexWnd::s_PointLastMouseMove != lParam)
{
CFlexWnd::s_hWndLastMouseMove = hWnd;
CFlexWnd::s_PointLastMouseMove = lParam;
CFlexWnd::s_dwLastMouseMove = GetTickCount(); // Get timestamp
CFlexWnd::s_ToolTip.SetEnable(FALSE);
CFlexWnd::s_ToolTip.SetToolTipParent(NULL);
}
}
switch (msg)
{
case WM_CREATE:
{
LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
if (lpcs == NULL)
break;
pThis = (CFlexWnd *)(void *)(lpcs->lpCreateParams);
assert(sizeof(HANDLE) == sizeof(CFlexWnd *));
SetProp(hWnd, sg_tszFlexWndPointerProp, (HANDLE)pThis);
if (pThis != NULL)
{
pThis->m_bIsDialog = FALSE;
pThis->SetHWND(hWnd);
}
break;
}
}
if (pThis != NULL)
return pThis->WndProc(hWnd, msg, wParam, lParam);
else
return DefWindowProc(hWnd, msg, wParam, lParam);
}
LRESULT CALLBACK __BaseFlexWndDialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
CFlexWnd *pThis = (CFlexWnd *)GetProp(hWnd, sg_tszFlexWndPointerProp);
switch (msg)
{
case WM_INITDIALOG:
pThis = (CFlexWnd *)(void *)lParam;
assert(sizeof(HANDLE) == sizeof(CFlexWnd *));
SetProp(hWnd, sg_tszFlexWndPointerProp, (HANDLE)pThis);
if (pThis != NULL)
{
pThis->m_bIsDialog = TRUE;
pThis->SetHWND(hWnd);
}
break;
}
if (pThis != NULL)
return (BOOL)pThis->WndProc(hWnd, msg, wParam, lParam);
else
return FALSE;
}
void CFlexWnd::Invalidate()
{
if (m_hWnd != NULL)
InvalidateRect(m_hWnd, NULL, TRUE);
}
SIZE CFlexWnd::GetClientSize() const
{
RECT rect = {0, 0, 0, 0};
if (m_hWnd != NULL)
::GetClientRect(m_hWnd, &rect);
SIZE size = {
rect.right - rect.left,
rect.bottom - rect.top};
return size;
}
void CFlexWnd::FillWndClass(HINSTANCE hInst)
{
sm_WndClass.cbSize = sizeof(WNDCLASSEX);
sm_WndClass.style = CS_DBLCLKS;
sm_WndClass.lpfnWndProc = __BaseFlexWndProc;
sm_WndClass.cbClsExtra = 0;
sm_WndClass.cbWndExtra = sizeof(CFlexWnd *);
sm_WndClass.hInstance = sm_hInstance = hInst;
sm_WndClass.hIcon = NULL;
sm_WndClass.hCursor = NULL;
sm_WndClass.hbrBackground = NULL;
sm_WndClass.lpszMenuName = NULL;
sm_WndClass.lpszClassName = sm_tszWndClassName;
sm_WndClass.hIconSm = NULL;
}
void CFlexWnd::RegisterWndClass(HINSTANCE hInst)
{
if (hInst == NULL)
{
assert(0);
return;
}
FillWndClass(hInst);
RegisterClassEx(&sm_WndClass);
sm_bWndClassRegistered = TRUE;
}
void CFlexWnd::UnregisterWndClass(HINSTANCE hInst)
{
if (hInst == NULL)
return;
UnregisterClass(sm_tszWndClassName, hInst);
sm_bWndClassRegistered = FALSE;
}
void CFlexWnd::GetClientRect(LPRECT lprect) const
{
if (lprect == NULL || m_hWnd == NULL)
return;
::GetClientRect(m_hWnd, lprect);
}
LPCTSTR CFlexWnd::GetDefaultClassName()
{
return CFlexWnd::sm_tszWndClassName;
}
void CFlexWnd::SetRenderMode(BOOL bRender)
{
if (bRender == m_bRender)
return;
m_bRender = bRender;
Invalidate();
}
BOOL CFlexWnd::InRenderMode()
{
return m_bRender;
}
void EnumChildWindowsZDown(HWND hParent, WNDENUMPROC proc, LPARAM lParam)
{
if (hParent == NULL || proc == NULL)
return;
HWND hWnd = GetWindow(hParent, GW_CHILD);
while (hWnd != NULL)
{
if (!proc(hWnd, lParam))
break;
hWnd = GetWindow(hWnd, GW_HWNDNEXT);
}
}
void EnumSiblingsAbove(HWND hParent, WNDENUMPROC proc, LPARAM lParam)
{
if (hParent == NULL || proc == NULL)
return;
HWND hWnd = hParent;
while (1)
{
hWnd = GetWindow(hWnd, GW_HWNDPREV);
if (hWnd == NULL)
break;
if (!proc(hWnd, lParam))
break;
}
}
static BOOL CALLBACK RenderIntoClipChild(HWND hWnd, LPARAM lParam)
{
CFlexWnd *pThis = (CFlexWnd *)(LPVOID)lParam;
return pThis->RenderIntoClipChild(hWnd);
}
static BOOL CALLBACK RenderIntoRenderChild(HWND hWnd, LPARAM lParam)
{
CFlexWnd *pThis = (CFlexWnd *)(LPVOID)lParam;
// Check if this is the immediate child. Do nothing if it's not immediate.
HWND hParent = GetParent(hWnd);
if (hParent != pThis->m_hWnd)
return TRUE;
return pThis->RenderIntoRenderChild(hWnd);
}
BOOL CFlexWnd::RenderIntoClipChild(HWND hChild)
{
if (m_hRenderInto != NULL && HasWnd() && hChild && IsWindowVisible(hChild))
{
RECT rect;
GetWindowRect(hChild, &rect);
POINT ul = {rect.left, rect.top}, lr = {rect.right, rect.bottom};
ScreenToClient(m_hWnd, &ul);
ScreenToClient(m_hWnd, &lr);
ExcludeClipRect(m_hRenderInto, ul.x, ul.y, lr.x, lr.y);
}
return TRUE;
}
BOOL CFlexWnd::RenderIntoRenderChild(HWND hChild)
{
CFlexWnd *pChild = GetFlexWnd(hChild);
if (m_hRenderInto != NULL && HasWnd() && pChild != NULL && IsWindowVisible(hChild))
{
RECT rect;
GetWindowRect(hChild, &rect);
POINT ul = {rect.left, rect.top};
ScreenToClient(m_hWnd, &ul);
pChild->RenderInto(m_hRenderInto, ul.x, ul.y);
}
return TRUE;
}
void CFlexWnd::RenderInto(HDC hDC, int x, int y)
{
if (hDC == NULL)
return;
int sdc = SaveDC(hDC);
{
OffsetViewportOrgEx(hDC, x, y, NULL);
SIZE size = GetClientSize();
IntersectClipRect(hDC, 0, 0, size.cx, size.cy);
m_hRenderInto = hDC;
int sdc2 = SaveDC(hDC);
{
EnumChildWindows/*ZDown*/(m_hWnd, ::RenderIntoClipChild, (LPARAM)(PVOID)this);
EnumSiblingsAbove(m_hWnd, ::RenderIntoClipChild, (LPARAM)(PVOID)this);
DoOnPaint(hDC);
}
if (sdc2)
RestoreDC(hDC, sdc2);
EnumChildWindows/*ZDown*/(m_hWnd, ::RenderIntoRenderChild, (LPARAM)(PVOID)this);
m_hRenderInto = NULL;
}
if (sdc)
RestoreDC(hDC, sdc);
}
void CFlexWnd::SetCapture()
{
::SetCapture(m_hWnd);
}
void CFlexWnd::ReleaseCapture()
{
::ReleaseCapture();
}
void CFlexWnd::DoOnPaint(HDC hDC)
{
OnPaint(hDC);
}

View File

@@ -0,0 +1,132 @@
//-----------------------------------------------------------------------------
// File: flexwnd.h
//
// Desc: CFlexWnd is a generic class that encapsulates the functionalities
// of a window. All other window classes are derived from CFlexWnd.
//
// Child classes can have different behavior by overriding the
// overridable message handlers (OnXXX members).
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __FLEXWND_H__
#define __FLEXWND_H__
#include "flexmsg.h"
class CFlexToolTip;
class CFlexWnd
{
public:
CFlexWnd();
~CFlexWnd();
// class registration
static void RegisterWndClass(HINSTANCE hInst);
static void UnregisterWndClass(HINSTANCE hInst);
// Unhighlight callouts when a click is made elsewhere besides the callouts
static HWND s_CurrPageHwnd;
// Tooltip
static CFlexToolTip s_ToolTip; // Shared tooltip window object
static DWORD s_dwLastMouseMove; // Last GetTickCount() that we have a WM_MOUSEMOVE
static HWND s_hWndLastMouseMove; // Last window handle of WM_MOUSEMOVE
static LPARAM s_PointLastMouseMove; // Last point of WM_MOUSEMOVE
// public read-only access to hwnd
const HWND &m_hWnd;
// creation
int DoModal(HWND hParent, int nTemplate, HINSTANCE hInst = NULL);
int DoModal(HWND hParent, LPCTSTR lpTemplate, HINSTANCE hInst = NULL);
HWND DoModeless(HWND hParent, int nTemplate, HINSTANCE hInst = NULL);
HWND DoModeless(HWND hParent, LPCTSTR lpTemplate, HINSTANCE hInst = NULL);
HWND Create(HWND hParent, LPCTSTR tszName, DWORD dwExStyle, DWORD dwStyle, const RECT &rect, HMENU hMenu = NULL);
HWND Create(HWND hParent, const RECT &rect, BOOL bVisible);
// destruction
void Destroy();
// operations
void RenderInto(HDC hDC, int x = 0, int y = 0);
void Invalidate();
// information
SIZE GetClientSize() const;
void GetClientRect(LPRECT) const;
static CFlexWnd *GetFlexWnd(HWND hWnd);
BOOL HasWnd() {return m_hWnd != NULL;}
static LPCTSTR GetDefaultClassName();
BOOL IsDialog();
BOOL InRenderMode();
void SetReadOnly(BOOL bReadOnly) { m_bReadOnly = bReadOnly; }
BOOL GetReadOnly() { return m_bReadOnly; }
// mouse capture
void SetCapture();
void ReleaseCapture();
protected:
// derived operations
void SetRenderMode(BOOL bRender = TRUE);
BOOL EndDialog(int);
// overridable message handlers
virtual void OnInit() {}
virtual LRESULT OnCreate(LPCREATESTRUCT lpCreateStruct) {return 0;}
virtual BOOL OnInitDialog() {return TRUE;}
virtual void OnTimer(UINT uID) {}
virtual BOOL OnEraseBkgnd(HDC hDC);
virtual void OnPaint(HDC hDC) {}
virtual void OnRender(BOOL bInternalCall = FALSE);
virtual LRESULT OnCommand(WORD wNotifyCode, WORD wID, HWND hWnd) {return 0;}
virtual LRESULT OnNotify(WPARAM wParam, LPARAM lParam) {return 0;}
virtual void OnMouseOver(POINT point, WPARAM fwKeys) {}
virtual void OnClick(POINT point, WPARAM fwKeys, BOOL bLeft) {}
virtual void OnWheel(POINT point, WPARAM wParam) {}
virtual void OnDoubleClick(POINT point, WPARAM fwKeys, BOOL bLeft) {}
virtual LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
virtual void OnDestroy() {}
private:
// implementation...
// information and initialization
int m_nID;
HWND m_privhWnd;
BOOL m_bIsDialog;
BOOL m_bReadOnly; // Whether this window is read-only (disabled).
void SetHWND(HWND hWnd);
void InitFlexWnd();
// paint helper (for inserting debug painting)
virtual void DoOnPaint(HDC hDC);
// render mode
BOOL m_bRender;
HDC m_hRenderInto;
BOOL RenderIntoClipChild(HWND hChild);
BOOL RenderIntoRenderChild(HWND hChild);
friend static BOOL CALLBACK RenderIntoClipChild(HWND hWnd, LPARAM lParam);
friend static BOOL CALLBACK RenderIntoRenderChild(HWND hWnd, LPARAM lParam);
// class information
static void FillWndClass(HINSTANCE hInst);
static BOOL sm_bWndClassRegistered;
static WNDCLASSEX sm_WndClass;
static LPCTSTR sm_tszWndClassName;
static HINSTANCE sm_hInstance;
friend LRESULT CALLBACK __BaseFlexWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
friend LRESULT CALLBACK __BaseFlexWndDialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
};
#endif //__FLEXWND_H__

View File

@@ -0,0 +1,15 @@
//-----------------------------------------------------------------------------
// File: guids.c
//
// Desc: Defines INITGUID and includes all headers with GUID definitions.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#define INITGUID
#include <dinput.h>
#include <dinputd.h>
#include <ddraw.h>
#include <d3d8.h>
#include "ourguids.h"

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,107 @@
//-----------------------------------------------------------------------------
// File: iclassfact.cpp
//
// Desc: Implements the class factory for the UI.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
//QI
STDMETHODIMP CFactory::QueryInterface(REFIID riid, LPVOID* ppv)
{
//null the put parameter
*ppv = NULL;
if ((riid == IID_IUnknown) || (riid == IID_IClassFactory))
{
*ppv = this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
//AddRef
STDMETHODIMP_(ULONG) CFactory::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
//Release
STDMETHODIMP_(ULONG) CFactory::Release()
{
if (InterlockedDecrement(&m_cRef) == 0)
{
delete this;
return 0;
}
return m_cRef;
}
//CreateInstance
STDMETHODIMP CFactory::CreateInstance(IUnknown* pUnkOuter, REFIID riid, LPVOID *ppv)
{
HRESULT hr = S_OK;
//can't aggregate
if (pUnkOuter != NULL)
{
return CLASS_E_NOAGGREGATION;
}
//create component
CDirectInputActionFramework* pDIActionFramework = new CDirectInputActionFramework();
if (pDIActionFramework == NULL)
{
return E_OUTOFMEMORY;
}
//get the requested interface
hr = pDIActionFramework->QueryInterface(riid, ppv);
//release IUnknown
pDIActionFramework->Release();
return hr;
}
//LockServer
STDMETHODIMP CFactory::LockServer(BOOL bLock)
{
HRESULT hr = S_OK;
if (bLock)
{
InterlockedIncrement(&g_cServerLocks);
}
else
{
InterlockedDecrement(&g_cServerLocks);
}
return hr;
}
//constructor
CFactory::CFactory()
{
m_cRef = 1;
}
//destructor
CFactory::~CFactory()
{
}

View File

@@ -0,0 +1,35 @@
//-----------------------------------------------------------------------------
// File: iclassfact.h
//
// Desc: Implements the class factory for the UI.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef _ICLASSFACT_H
#define _ICLASSFACT_H
class CFactory : public IClassFactory
{
public:
//IUnknown
STDMETHOD (QueryInterface) (REFIID riid, LPVOID* ppv);
STDMETHOD_(ULONG, AddRef) ();
STDMETHOD_(ULONG, Release) ();
//IClassFactory
STDMETHOD (CreateInstance) (IUnknown* pUnkOuter, REFIID riid, LPVOID* ppv);
STDMETHOD (LockServer) (BOOL bLock);
//constructor/destructor
CFactory();
~CFactory();
protected:
LONG m_cRef;
};
#endif // _ICLASSFACT_H

View File

@@ -0,0 +1,41 @@
#ifndef __ID3DSURF_H__
#define __ID3DSURF_H__
class IDirect3DSurface8Clone : public IUnknown
{
public:
//IUnknown
STDMETHOD (QueryInterface) (REFIID iid, LPVOID *ppv) PURE;
STDMETHOD_(ULONG, AddRef) () PURE;
STDMETHOD_(ULONG, Release) () PURE;
// Surface
STDMETHOD (SetPrivateData) (REFGUID riid,
CONST VOID *pvData,
DWORD cbData,
DWORD dwFlags) PURE;
STDMETHOD (GetPrivateData) (REFGUID riid,
VOID *pvData,
DWORD *pcbData) PURE;
STDMETHOD (FreePrivateData) (REFGUID riid) PURE;
STDMETHOD (GetContainer) (REFIID riid,
void **ppContainer) PURE;
STDMETHOD (GetDevice) (IDirect3DDevice8 **ppDevice) PURE;
STDMETHOD_(D3DSURFACE_DESC, GetDesc)() PURE;
STDMETHOD (LockRect)(D3DLOCKED_RECT *pLockedRectData,
CONST RECT *pRect,
DWORD dwFlags) PURE;
STDMETHOD (UnlockRect)() PURE;
};
IDirect3DSurface8 *GetCloneSurface(int iWidth, int iHeight);
#endif

View File

@@ -0,0 +1,62 @@
//-----------------------------------------------------------------------------
// File: idiacpage.h
//
// Desc: IDIDeviceActionConfigPage is a COM interface for
// CDIDeviceActionConfigPage. CConfigWnd uses this interface to access
// the pages in UI.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __IDIACPAGE_H__
#define __IDIACPAGE_H__
typedef struct _DICFGPAGECREATESTRUCT {
DWORD dwSize;
int nPage;
HWND hParentWnd;
RECT rect;
HWND hPageWnd; // out
DIDEVICEINSTANCEW didi;
LPDIRECTINPUTDEVICE8W lpDID;
CUIGlobals *pUIGlobals;
IDIConfigUIFrameWindow *pUIFrame;
} DICFGPAGECREATESTRUCT;
class IDIDeviceActionConfigPage : public IUnknown
{
public:
//IUnknown fns
STDMETHOD (QueryInterface) (REFIID iid, LPVOID *ppv) PURE;
STDMETHOD_(ULONG, AddRef) () PURE;
STDMETHOD_(ULONG, Release) () PURE;
//IDirectInputActionConfigPage
STDMETHOD (Create) (DICFGPAGECREATESTRUCT *pcs) PURE;
STDMETHOD (Show) (LPDIACTIONFORMATW lpDiActFor) PURE;
STDMETHOD (Hide) () PURE;
// layout edit mode
STDMETHOD (SetEditLayout) (BOOL bEditLayout) PURE;
// Set the info box text
STDMETHOD (SetInfoText) (int iCode) PURE;
// Unacquire and Reacquire the device for page's purposes
// (the configwnd needs to do this around SetActionMap() calls)
STDMETHOD (Unacquire) () PURE;
STDMETHOD (Reacquire) () PURE;
};
#endif //__IDIACPAGE_H__

View File

@@ -0,0 +1,29 @@
//-----------------------------------------------------------------------------
// File: ifrmwrk.h
//
// Desc: Contains the interface definition for the UI framework.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef _IFRMWRK_H
#define _IFRMWRK_H
class IDirectInputActionFramework : public IUnknown
{
public:
//IUnknown fns
STDMETHOD (QueryInterface) (REFIID iid, LPVOID *ppv) PURE;
STDMETHOD_(ULONG, AddRef) () PURE;
STDMETHOD_(ULONG, Release) () PURE;
//own fns
STDMETHOD (ConfigureDevices) (LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
LPDICONFIGUREDEVICESPARAMSW lpdiCDParams,
DWORD dwFlags,
LPVOID pvRefData
) PURE;
};
#endif // _IFRMWRK_H

View File

@@ -0,0 +1,107 @@
//-----------------------------------------------------------------------------
// File: ipageclassfact.cpp
//
// Desc: Implements the class factory for the page object.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
//QI
STDMETHODIMP CPageFactory::QueryInterface(REFIID riid, LPVOID* ppv)
{
//null the put parameter
*ppv = NULL;
if ((riid == IID_IUnknown) || (riid == IID_IClassFactory))
{
*ppv = this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
//AddRef
STDMETHODIMP_(ULONG) CPageFactory::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
//Release
STDMETHODIMP_(ULONG) CPageFactory::Release()
{
if (InterlockedDecrement(&m_cRef) == 0)
{
delete this;
return 0;
}
return m_cRef;
}
//CreateInstance
STDMETHODIMP CPageFactory::CreateInstance(IUnknown* pUnkOuter, REFIID riid, LPVOID *ppv)
{
HRESULT hr = S_OK;
//can't aggregate
if (pUnkOuter != NULL)
{
return CLASS_E_NOAGGREGATION;
}
//create component
CDIDeviceActionConfigPage* pFE = new CDIDeviceActionConfigPage();
if (pFE == NULL)
{
return E_OUTOFMEMORY;
}
//get the requested interface
hr = pFE->QueryInterface(riid, ppv);
//release IUnknown
pFE->Release();
return hr;
}
//LockServer
STDMETHODIMP CPageFactory::LockServer(BOOL bLock)
{
HRESULT hr = S_OK;
if (bLock)
{
InterlockedIncrement(&g_cServerLocks);
}
else
{
InterlockedDecrement(&g_cServerLocks);
}
return hr;
}
//constructor
CPageFactory::CPageFactory()
{
m_cRef = 1;
}
//destructor
CPageFactory::~CPageFactory()
{
}

View File

@@ -0,0 +1,35 @@
//-----------------------------------------------------------------------------
// File: ipageclassfact.h
//
// Desc: Implements the class factory for the page object.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef _IPAGECLASSFACT_H
#define _IPAGECLASSFACT_H
class CPageFactory : public IClassFactory
{
public:
//IUnknown
STDMETHOD (QueryInterface) (REFIID riid, LPVOID* ppv);
STDMETHOD_(ULONG, AddRef) ();
STDMETHOD_(ULONG, Release) ();
//IClassFactory
STDMETHOD (CreateInstance) (IUnknown* pUnkOuter, REFIID riid, LPVOID* ppv);
STDMETHOD (LockServer) (BOOL bLock);
//constructor/destructor
CPageFactory();
~CPageFactory();
protected:
LONG m_cRef;
};
#endif // _IPAGECLASSFACT_H

View File

@@ -0,0 +1,41 @@
//-----------------------------------------------------------------------------
// File: iuiframe.h
//
// Desc: Defines the interface of IDIConfigUIFrameWindow, which is used by
// CConfigWnd.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __IUIFRAME_H__
#define __IUIFRAME_H__
class IDIConfigUIFrameWindow
{
public:
// Reset Entire Configuration
STDMETHOD (Reset) () PURE;
// Assignment Querying. GuidInstance is the guid of the device initiating the query.
STDMETHOD (QueryActionAssignedAnywhere) (GUID GuidInstance, int i) PURE;
// Genre Control
STDMETHOD_(int, GetNumGenres) () PURE;
STDMETHOD (SetCurGenre) (int i) PURE;
STDMETHOD_(int, GetCurGenre) () PURE;
// User Control
STDMETHOD_(int, GetNumUsers) () PURE;
STDMETHOD (SetCurUser) (int nPage, int nUser) PURE;
STDMETHOD_(int, GetCurUser) (int nPage) PURE;
// ActionFormat Access
STDMETHOD (GetActionFormatFromInstanceGuid) (LPDIACTIONFORMATW *lplpAcFor, REFGUID) PURE;
// Main HWND Access
STDMETHOD_(HWND, GetMainHWND) () PURE;
};
#endif //__IUIFRAME_H__

View File

@@ -0,0 +1,63 @@
#ifndef __LTRACE_H__
#define __LTRACE_H__
#define NO_LTRACE
/*#ifndef NO_LTRACE
#ifdef NDEBUG
#error I want ltrace!
#define NO_LTRACE
#endif
#endif*/
#ifndef NO_LTRACE
#ifndef THIS_FILE
const TCHAR THIS_FILE[] = __FILE__;
#endif
class __CLTraceScope
{
public:
__CLTraceScope(LPCTSTR, LPCTSTR, int);
__CLTraceScope(LPCTSTR, int);
~__CLTraceScope();
void scope(LPCTSTR, ...);
void ltrace(LPCTSTR, ...);
private:
LPCTSTR spacing();
LPCTSTR m_scope, m_file;
int m_line;
int m_depth;
static int s_depth;
// __CLTraceScope *m_pprev, *m_pnext;
// static __CLTraceScope *s_pfirst, *s_plast;
};
#define LTSCOPE0(scope) __CLTraceScope __localscope(scope, THIS_FILE, __LINE__)
#define LTSCOPE __CLTraceScope __localscope(THIS_FILE, __LINE__); __localscope.scope
#define LTRACE __localscope.ltrace
#else
inline void __localscope_dummy(LPCTSTR, ...) {}
#define LTSCOPE0(scope) (void(0))
#define LTSCOPE ; __localscope_dummy
#define LTRACE __localscope_dummy
#endif
#endif //__LTRACE_H__

View File

@@ -0,0 +1,124 @@
//-----------------------------------------------------------------------------
// File: main.cpp
//
// Desc: Contains global data and DllMain.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
HMODULE g_hModule = NULL;
long g_cComponents = 0;
long g_cServerLocks = 0;
//exported fns
//can unload?
STDAPI DllCanUnloadNow()
{
if ((g_cComponents == 0) && (g_cServerLocks == 0))
{
return S_OK;
}
else
{
return S_FALSE;
}
}
//get class factory
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
HRESULT hr = S_OK;
//check which class it is
if ((rclsid != CLSID_CDirectInputActionFramework)
&& (rclsid != CLSID_CDIDeviceActionConfigPage)
)
{
return CLASS_E_CLASSNOTAVAILABLE;
}
//create the appropriate class factory
IClassFactory* pFact = NULL;
if (rclsid == CLSID_CDirectInputActionFramework)
pFact = new CFactory();
if (rclsid == CLSID_CDIDeviceActionConfigPage)
pFact = new CPageFactory();
if (pFact == NULL)
return E_OUTOFMEMORY;
hr = pFact->QueryInterface(riid, ppv);
pFact->Release();
return hr;
}
//dll module information
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
g_hModule = (HMODULE)hModule;
CFlexWnd::RegisterWndClass((HINSTANCE)hModule);
break;
case DLL_PROCESS_DETACH:
CFlexWnd::UnregisterWndClass((HINSTANCE)hModule);
break;
}
return TRUE;
}
//server registration
STDAPI DllRegisterServer()
{
HRESULT hr1 = S_OK, hr2 = S_OK, hr3 = S_OK;
hr1 = RegisterServer(g_hModule, CLSID_CDirectInputActionFramework, _T("CLSID_CDirectInputActionFramework"), _T("DIACTFRM"), _T("DIACTFRM.1"));
hr2 = RegisterServer(g_hModule, CLSID_CDIDeviceActionConfigPage, _T("CLSID_CDIDeviceActionConfigPage"), _T("DIACTFRM"), _T("DIACTFRM.1"));
if (FAILED(hr1))
return hr1;
if (FAILED(hr2))
return hr2;
if (FAILED(hr3))
return hr3;
return S_OK;
}
//server unregistration
STDAPI DllUnregisterServer()
{
HRESULT hr1 = S_OK, hr2 = S_OK, hr3 = S_OK;
hr1 = UnregisterServer(CLSID_CDirectInputActionFramework, _T("DIACTFRM"), _T("DIACTFRM.1"));
hr2 = UnregisterServer(CLSID_CDIDeviceActionConfigPage, _T("DIACTFRM"), _T("DIACTFRM.1"));
if (FAILED(hr1))
return hr1;
if (FAILED(hr2))
return hr2;
if (FAILED(hr3))
return hr3;
return S_OK;
}

View File

@@ -0,0 +1,18 @@
//-----------------------------------------------------------------------------
// File: main.h
//
// Desc: Contains global data and DllMain.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __CFGUI_MAIN_H__
#define __CFGUI_MAIN_H__
extern HMODULE g_hModule;
extern long g_cComponents;
extern long g_cServerLocks;
#endif //__CFGUI_MAIN_H__

View File

@@ -0,0 +1,38 @@
//-----------------------------------------------------------------------------
// File: ourguids.h
//
// Desc: Contains the definitions of the UI's GUIDs.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __CFGUI_OURGUIDS_H__
#define __CFGUI_OURGUIDS_H__
#include <objbase.h>
// {0A484F30-956C-43d0-A5C9-587E2B2EA910}
DEFINE_GUID(IID_IDirectInputConfigUITest,
0xa484f30, 0x956c, 0x43d0, 0xa5, 0xc9, 0x58, 0x7e, 0x2b, 0x2e, 0xa9, 0x10);
// {F4279160-608F-11d3-8FB2-00C04F8EC627}
DEFINE_GUID(IID_IDIActionFramework,
0xf4279160, 0x608f, 0x11d3, 0x8f, 0xb2, 0x0, 0xc0, 0x4f, 0x8e, 0xc6, 0x27);
// {9F34AF20-6095-11d3-8FB2-00C04F8EC627}
DEFINE_GUID(CLSID_CDirectInputActionFramework,
0x9f34af20, 0x6095, 0x11d3, 0x8f, 0xb2, 0x0, 0xc0, 0x4f, 0x8e, 0xc6, 0x27);
// {72BB1241-5CA8-11d3-8FB2-00C04F8EC627}
DEFINE_GUID(IID_IDIDeviceActionConfigPage,
0x72bb1241, 0x5ca8, 0x11d3, 0x8f, 0xb2, 0x0, 0xc0, 0x4f, 0x8e, 0xc6, 0x27);
// {18AB439E-FCF4-40d4-90DA-F79BAA3B0655}
DEFINE_GUID(CLSID_CDIDeviceActionConfigPage,
0x18ab439e, 0xfcf4, 0x40d4, 0x90, 0xda, 0xf7, 0x9b, 0xaa, 0x3b, 0x6, 0x55);
#endif //__CFGUI_OURGUIDS_H__

View File

@@ -0,0 +1,39 @@
#ifndef __PAGECOMMON_H_RECURSE__
#ifndef __PAGECOMMON_H__
#define __PAGECOMMON_H__
// recurse into this header to get forward declarations first,
// then full definitions
#define __PAGECOMMON_H_RECURSE__
#define FORWARD_DECLS
#include "pagecommon.h"
#undef FORWARD_DECLS
#include "pagecommon.h"
#undef __PAGECOMMON_H_RECURSE__
#endif //__PAGECOMMON_H__
#else // __PAGECOMMON_H_RECURSE__
// class includes in non-pointer dependency order
#include "cdeviceui.h"
#include "cdeviceview.h"
#include "cdeviceviewtext.h"
#include "cdevicecontrol.h"
#include "populate.h"
#include "selcontroldlg.h"
#include "viewselwnd.h"
#include "cdiacpage.h"
#endif // __PAGECOMMON_H_RECURSE__

View File

@@ -0,0 +1,527 @@
//-----------------------------------------------------------------------------
// File: populate.cpp
//
// Desc: This file contains the population functions. These are all
// accessed through PopulateAppropriately(). That function creates
// views & controls based on the type of the device that the passed
// DeviceUI represents.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
// these functions are internal to this filed, called only by
// PopulateAppropriately().
HRESULT PopulateViaGetImageInfo(CDeviceUI &ui);
HRESULT PopulateFromImageInfoHeader(CDeviceUI &ui, const DIDEVICEIMAGEINFOHEADERW &);
HRESULT PopulateListView(CDeviceUI &ui);
HRESULT PopulateErrorView(CDeviceUI &ui);
// Clears the entire passed DeviceUI, then fills it with views and
// controls based on device type. Tries to gaurantee that there will
// be at least one view.
HRESULT PopulateAppropriately(CDeviceUI &ui)
{
HRESULT hr = S_OK;
// first empty the ui
ui.Unpopulate();
// get device type
DWORD dwdt = ui.m_didi.dwDevType;
DWORD dwType = (DWORD)(LOBYTE(LOWORD(dwdt)));
DWORD dwSubType = (DWORD)(HIBYTE(LOWORD(dwdt)));
// based on type...
switch (dwType)
{
default:
// unless its a type we don't ever want views for,
// populate via the GetImageInfo() API
hr = PopulateViaGetImageInfo(ui);
if (SUCCEEDED(hr) && ui.GetNumViews() > 0)
return hr;
// if it failed or resulted in nothing,
// clear anything that might've been added
ui.Unpopulate();
// intentional fallthrough
case DI8DEVTYPE_MOUSE:
case DI8DEVTYPE_KEYBOARD:
// for types that we don't ever want views for
// we populate the list view without trying the above
hr = PopulateListView(ui);
// if we still failed or don't have any views,
// populate with error message view
if (FAILED(hr) || ui.GetNumViews() < 1)
{
// empty
ui.Unpopulate();
// show error message
hr = PopulateErrorView(ui);
}
// this function should guarantee success
assert(!FAILED(hr));
return hr;
}
}
// Calls the GetImageInfo() API to get the view images and controls
// for the entire device, and returns a failure if there's the
// slightest problem (if GII() fails, or if an image fails to load,
// etc.)
HRESULT PopulateViaGetImageInfo(CDeviceUI &ui)
{
if (!ui.m_lpDID)
return E_FAIL;
HRESULT hr = S_OK;
DIDEVICEIMAGEINFOHEADERW m_diImgInfoHdr;
LPDIDEVICEIMAGEINFOW &lprgdiImgData = m_diImgInfoHdr.lprgImageInfoArray;
ZeroMemory( &m_diImgInfoHdr, sizeof(DIDEVICEIMAGEINFOHEADERW) );
m_diImgInfoHdr.dwSize = sizeof(DIDEVICEIMAGEINFOHEADERW);
m_diImgInfoHdr.dwSizeImageInfo = sizeof(DIDEVICEIMAGEINFOW);
// Retrieve the required buffer size.
hr = ui.m_lpDID->GetImageInfo( &m_diImgInfoHdr );
if (FAILED(hr))
{
etrace1(_T("GetImageInfo() failed while trying to get required buffer size. hr = 0x%08x\n"), hr);
return E_FAIL;
}
// Allocate the buffer.
lprgdiImgData = (LPDIDEVICEIMAGEINFOW) malloc( (size_t)
(m_diImgInfoHdr.dwBufferSize = m_diImgInfoHdr.dwBufferUsed) );
if (lprgdiImgData == NULL)
{
etrace1(_T("Could not allocate buffer of size %d.\n"), m_diImgInfoHdr.dwBufferSize);
return E_FAIL;
}
trace(_T("Allocated buffer.\n"));
traceDWORD(m_diImgInfoHdr.dwBufferSize);
m_diImgInfoHdr.lprgImageInfoArray = lprgdiImgData;
// Get the display info.
hr = ui.m_lpDID->GetImageInfo( &m_diImgInfoHdr );
if (FAILED(hr))
{
etrace1(_T("GetImageInfo() failed trying to get image info. hr = 0x%08x\n"), hr);
free(lprgdiImgData);
lprgdiImgData = NULL;
return E_FAIL;
}
// actually populate now
traceDWORD(m_diImgInfoHdr.dwBufferUsed);
hr = PopulateFromImageInfoHeader(ui, m_diImgInfoHdr);
if (FAILED(hr))
return hr;
// free stuff
free(lprgdiImgData);
lprgdiImgData = NULL;
return S_OK;
}
// basically does the work for the above function after the header
// is actually retrieved
HRESULT PopulateFromImageInfoHeader(CDeviceUI &ui, const DIDEVICEIMAGEINFOHEADERW &dih)
{
tracescope(ts1, _T("CGetImageInfoPopHelper::Init()...\n"));
traceDWORD(dih.dwSizeImageInfo);
traceDWORD(dih.dwBufferSize);
traceDWORD(dih.dwBufferUsed);
if (dih.dwSizeImageInfo != sizeof(DIDEVICEIMAGEINFOW))
{
etrace(_T("dwSizeImageInfo Incorrect.\n"));
assert(0);
return E_FAIL;
}
DWORD dwNumElements = dih.dwBufferUsed / dih.dwSizeImageInfo;
if (dwNumElements * dih.dwSizeImageInfo != dih.dwBufferUsed
|| dih.dwBufferUsed < dih.dwBufferSize)
{
etrace(_T("Could not confidently calculate dwNumElements.\n"));
assert(0);
return E_FAIL;
}
DWORD i;
traceDWORD(dwNumElements);
bidirlookup<DWORD, int> offset_view;
{
tracescope(ts2, _T("First Pass...\n"));
for (i = 0; i < dwNumElements; i++)
if (dih.lprgImageInfoArray[i].dwFlags & DIDIFT_CONFIGURATION)
{
LPDIDEVICEIMAGEINFOW lpInfoBase = dih.lprgImageInfoArray;
DWORD index = i;
{
tracescope(ts1, _T("AddViewInfo()...\n"));
traceHEXPTR(lpInfoBase);
traceDWORD(index);
if (lpInfoBase == NULL)
{
etrace(_T("lpInfoBase NULL\n"));
return E_FAIL;
}
DIDEVICEIMAGEINFOW &info = lpInfoBase[index];
DWORD dwOffset = index;
// add view info to array
CDeviceView *pView = ui.NewView();
if (!pView)
{
etrace(_T("Could not create new view.\n"));
return E_FAIL;
}
int nView = pView->GetViewIndex();
tracescope(ts2, _T("Adding View "));
trace2(_T("%d (info index %u)\n"), nView, index);
// set view's imagepath
if (!info.tszImagePath)
{
etrace(_T("No image path.\n"));
return E_FAIL;
}
LPTSTR tszImagePath = AllocLPTSTR(info.tszImagePath);
if (!tszImagePath)
{
etrace(_T("Could not copy image path.\n"));
return E_FAIL;
}
// set the view's image path
pView->SetImagePath(tszImagePath);
// create bitmap from path
LPDIRECT3DSURFACE8 lpSurf3D = ui.m_uig.GetSurface3D();
CBitmap *pbm = CBitmap::CreateViaD3DX(tszImagePath, lpSurf3D);
traceSTR(info.tszImagePath);
traceHEXPTR(pbm);
traceDWORD(dwOffset);
free(tszImagePath);
tszImagePath = NULL;
if (lpSurf3D)
{
lpSurf3D->Release(); // Need to free the surface instance after we are done as AddRef() was called earlier.
lpSurf3D = NULL;
}
if (!pbm)
{
etrace(_T("Could not create image from path.\n"));
return E_FAIL;
}
// set the view's image
assert(pbm != NULL);
pView->SetImage(pbm); // setimage steals the bitmap pointer
assert(pbm == NULL);
// add conversion from offset to view
offset_view.add(dwOffset, nView);
}
}
}
{
tracescope(ts2, _T("Second Pass...\n"));
for (i = 0; i < dwNumElements; i++)
{
DWORD dwFlags = dih.lprgImageInfoArray[i].dwFlags;
if (dwFlags & DIDIFT_OVERLAY)
{
LPDIDEVICEIMAGEINFOW lpInfoBase = dih.lprgImageInfoArray;
DWORD index = i;
{
tracescope(ts1, _T("AddControlInfo()...\n"));
traceHEXPTR(lpInfoBase);
traceDWORD(index);
if (lpInfoBase == NULL)
{
etrace(_T("lpInfoBase NULL\n"));
return E_FAIL;
}
DIDEVICEIMAGEINFOW &info = lpInfoBase[index];
int nViewIndex = 0;
if (!offset_view.getright(info.dwViewID, nViewIndex))
{
etrace(_T("Could not get view index\n"));
return E_FAIL;
}
if (nViewIndex < 0 || nViewIndex >= ui.GetNumViews())
{
etrace1(_T("Invalid view index %d\n"), nViewIndex);
return E_FAIL;
}
CDeviceView *pView = ui.GetView(nViewIndex);
if (!pView)
{
etrace1(_T("\n"), nViewIndex);
return E_FAIL;
}
CDeviceControl *pControl = pView->NewControl();
int nControl = pControl->GetControlIndex();
tracescope(ts2, _T("Adding Control "));
trace4(_T("%d (info index %u) to view %d (info index %u)\n"), nControl, index, nViewIndex, info.dwViewID);
traceDWORD(info.dwObjID);
traceDWORD(info.dwcValidPts);
traceRECT(info.rcCalloutRect);
traceRECT(info.rcOverlay);
traceHEX(info.dwTextAlign);
traceSTR(info.tszImagePath);
pControl->SetObjID(info.dwObjID);
pControl->SetLinePoints(int(info.dwcValidPts), info.rgptCalloutLine);
pControl->SetCalloutMaxRect(info.rcCalloutRect);
pControl->SetAlignment(info.dwTextAlign);
if (info.tszImagePath)
{
LPTSTR tszOverlayPath = AllocLPTSTR(info.tszImagePath);
if (tszOverlayPath)
pControl->SetOverlayPath(tszOverlayPath);
free(tszOverlayPath);
tszOverlayPath = NULL;
}
pControl->SetOverlayRect(info.rcOverlay);
pControl->Init();
}
}
}
}
return S_OK;
}
// Enumerates the controls on the device and creates one big list
// view for the device. Fails if it can't enumerate for some reason.
HRESULT PopulateListView(CDeviceUI &ui)
{
int i;
HRESULT hr = S_OK;
// we must have the device interface
if (!ui.m_lpDID)
return E_FAIL;
// create one view
CDeviceView *pView = ui.NewView();
if (!pView)
return E_FAIL;
// enable scrolling on it
pView->EnableScrolling();
// get list of controls
DIDEVOBJSTRUCT os;
hr = FillDIDeviceObjectStruct(os, ui.m_lpDID);
if (FAILED(hr))
return hr;
// if there aren't any, fail
int n = os.nObjects;
if (n < 1)
return E_FAIL;
// run through and create a text for every control to
// get the sizing
POINT origin = {0, 0};
SIZE max = {0, 0};
for (i = 0; i < n; i++)
{
LPTSTR tszName = AllocLPTSTR(os.pdoi[i].tszName);
CDeviceViewText *pText = pView->AddText(
(HFONT)ui.m_uig.GetFont(UIE_DEVOBJ),
ui.m_uig.GetTextColor(UIE_DEVOBJ),
ui.m_uig.GetBkColor(UIE_DEVOBJ),
origin,
tszName);
free(tszName);
if (!pText)
return E_FAIL;
SIZE tsize = GetRectSize(pText->GetRect());
if (tsize.cx > max.cx)
max.cx = tsize.cx;
if (tsize.cy > max.cy)
max.cy = tsize.cy;
}
// Find out if we should use one column or two columns if this is a kbd device.
BOOL bUseTwoColumns = FALSE;
if (LOBYTE(LOWORD(ui.m_didi.dwDevType)) == DI8DEVTYPE_KEYBOARD &&
((g_sizeImage.cx - DEFAULTVIEWSBWIDTH) >> 1) - max.cx >= MINLISTVIEWCALLOUTWIDTH)
bUseTwoColumns = TRUE;
// calculate max callout height based on the two possible fonts
int cmaxh = 0,
ch = 2 + GetTextHeight((HFONT)ui.m_uig.GetFont(UIE_CALLOUT)),
chh = 2 + GetTextHeight((HFONT)ui.m_uig.GetFont(UIE_CALLOUTHIGH));
if (ch > cmaxh)
cmaxh = ch;
if (chh > cmaxh)
cmaxh = chh;
// calculate the bigger of text/callout
int h = 0;
if (cmaxh > h)
h = cmaxh;
if (max.cy > h)
h = max.cy;
// calculate vertical offsets of text/callout within max spacing
int to = (h - max.cy) / 2,
co = (h - cmaxh) / 2;
// max width for text is half of the view window
if (max.cx > ((g_sizeImage.cx - DEFAULTVIEWSBWIDTH) >> 1))
max.cx = ((g_sizeImage.cx - DEFAULTVIEWSBWIDTH) >> 1);
// go back through all the controls and place the text while
// creating the corresponding callouts
HDC hDC = CreateCompatibleDC(NULL);
CPaintHelper ph(ui.m_uig, hDC);
ph.SetElement(UIE_DEVOBJ);
int at = 0; // Start at second row since first row is used for header. Also half row spacing
for (i = 0; i < n; i++)
{
// reposition the text
CDeviceViewText *pText = pView->GetText(i);
if (!pText)
{
DeleteDC(hDC);
return E_FAIL;
}
SIZE s = GetRectSize(pText->GetRect());
if (bUseTwoColumns)
{
int iXOffset = i & 1 ? ((g_sizeImage.cx - DEFAULTVIEWSBWIDTH) >> 1) : 0;
RECT rect = {iXOffset,
at + to,
max.cx + iXOffset,
at + to + s.cy};
// Get the rectangle that is actually used.
RECT adjrect = rect;
if (hDC)
{
DrawText(hDC, pText->GetText(), -1, &adjrect, DT_NOPREFIX|DT_CALCRECT);
// If the rect actually used is smaller than the space available, use the smaller rect and align to right.
if (adjrect.right < rect.right)
rect.left += rect.right - adjrect.right;
}
pText->SetRect(rect);
}
else
{
RECT rect = {0, at + to, max.cx /*> ((g_sizeImage.cx - DEFAULTVIEWSBWIDTH) >> 1) ?
((g_sizeImage.cx - DEFAULTVIEWSBWIDTH) >> 1) : max.cx*/, at + to + s.cy};
pText->SetRect(rect);
}
// create the control
CDeviceControl *pControl = pView->NewControl();
if (!pControl)
{
DeleteDC(hDC);
return E_FAIL;
}
// position it
RECT rect = {max.cx + 10, at, (g_sizeImage.cx - DEFAULTVIEWSBWIDTH) >> 1, at + h};
// If single column, extend callout all the way to right end of view window
if (!bUseTwoColumns)
rect.right = g_sizeImage.cx - DEFAULTVIEWSBWIDTH;
// If this is a keyboard, move to right column on odd numbered controls.
if (bUseTwoColumns && (i & 1))
{
rect.left += (g_sizeImage.cx - DEFAULTVIEWSBWIDTH) >> 1;
rect.right = g_sizeImage.cx - DEFAULTVIEWSBWIDTH;
}
pControl->SetCalloutMaxRect(rect);
// align it
pControl->SetAlignment(CAF_LEFT);
// set approp offset
pControl->SetObjID(os.pdoi[i].dwType);
// init it
pControl->Init();
// go to next y coord
// If this is a keyboard, then only increase y when we are moving to even numbered controls.
if (!bUseTwoColumns || (i & 1))
at += h;
}
DeleteDC(hDC);
// make selection/thumb images (just for kicks)
pView->MakeMissingImages();
// calculate view dimensions (for scrolling)
pView->CalcDimensions();
return S_OK;
}
// Creates a single view with an error message. Should not fail.
HRESULT PopulateErrorView(CDeviceUI &ui)
{
// create the new view
CDeviceView *pView = ui.NewView();
if (!pView)
return E_FAIL;
// add text objects containing error message
pView->AddWrappedLineOfText(
(HFONT)ui.m_uig.GetFont(UIE_ERRORHEADER),
ui.m_uig.GetTextColor(UIE_ERRORHEADER),
ui.m_uig.GetBkColor(UIE_ERRORHEADER),
_T("Error!"));
pView->AddWrappedLineOfText(
(HFONT)ui.m_uig.GetFont(UIE_ERRORMESSAGE),
ui.m_uig.GetTextColor(UIE_ERRORMESSAGE),
ui.m_uig.GetBkColor(UIE_ERRORMESSAGE),
_T("Could not create views for device."));
pView->MakeMissingImages();
return S_OK;
}

View File

@@ -0,0 +1,16 @@
//-----------------------------------------------------------------------------
// File: populate.h
//
// Desc: Implements PopulateAppropriately.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __POPULATE_H__
#define __POPULATE_H__
HRESULT PopulateAppropriately(CDeviceUI &ui);
#endif //__POPULATE_H__

View File

@@ -0,0 +1,511 @@
#include "common.hpp"
/*****************************************************************************
*
* privcom.c
*
* Copyright (c) 2000 Microsoft Corporation. All Rights Reserved.
*
* Abstract:
*
* Functions that sort-of duplicate what OLE does.
*
* Adapted from dinput\dx8\dll\dioledup.c
*
*****************************************************************************/
typedef LPUNKNOWN PUNK;
typedef LPVOID PV, *PPV;
typedef CONST VOID *PCV;
typedef REFIID RIID;
typedef CONST GUID *PCGUID;
/*
* Convert an object (X) to a count of bytes (cb).
*/
#define cbX(X) sizeof(X)
/*
* Convert an array name (A) to a generic count (c).
*/
#define cA(a) (cbX(a)/cbX(a[0]))
/*
* Convert a count of X's (cx) into a count of bytes
* and vice versa.
*/
#define cbCxX(cx, X) ((cx) * cbX(X))
#define cxCbX(cb, X) ((cb) / cbX(X))
/*
* Convert a count of chars (cch), tchars (ctch), wchars (cwch),
* or dwords (cdw) into a count of bytes, and vice versa.
*/
#define cbCch(cch) cbCxX( cch, CHAR)
#define cbCwch(cwch) cbCxX(cwch, WCHAR)
#define cbCtch(ctch) cbCxX(ctch, TCHAR)
#define cbCdw(cdw) cbCxX( cdw, DWORD)
#define cchCb(cb) cxCbX(cb, CHAR)
#define cwchCb(cb) cxCbX(cb, WCHAR)
#define ctchCb(cb) cxCbX(cb, TCHAR)
#define cdwCb(cb) cxCbX(cb, DWORD)
// yay
#define ctchGuid (1 + 8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12 + 1 + 1)
/*****************************************************************************
*
* _ParseHex
*
* Parse a hex string encoding cb bytes (at most 4), then
* expect the tchDelim to appear afterwards. If chDelim is 0,
* then no delimiter is expected.
*
* Store the result into the indicated LPBYTE (using only the
* size requested), updating it, and return a pointer to the
* next unparsed character, or 0 on error.
*
* If the incoming pointer is also 0, then return 0 immediately.
*
*****************************************************************************/
LPCTSTR
_ParseHex(LPCTSTR ptsz, LPBYTE *ppb, int cb, TCHAR tchDelim)
{
if(ptsz)
{
int i = cb * 2;
DWORD dwParse = 0;
do
{
DWORD uch;
uch = (TBYTE)*ptsz - TEXT('0');
if(uch < 10)
{ /* a decimal digit */
} else
{
uch = (*ptsz | 0x20) - TEXT('a');
if(uch < 6)
{ /* a hex digit */
uch += 10;
} else
{
return 0; /* Parse error */
}
}
dwParse = (dwParse << 4) + uch;
ptsz++;
} while(--i);
if(tchDelim && *ptsz++ != tchDelim) return 0; /* Parse error */
for(i = 0; i < cb; i++)
{
(*ppb)[i] = ((LPBYTE)&dwParse)[i];
}
*ppb += cb;
}
return ptsz;
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func BOOL | ParseGUID |
*
* Take a string and convert it into a GUID, return success/failure.
*
* @parm OUT LPGUID | lpGUID |
*
* Receives the parsed GUID on success.
*
* @parm IN LPCTSTR | ptsz |
*
* The string to parse. The format is
*
* { <lt>dword<gt> - <lt>word<gt> - <lt>word<gt>
* - <lt>byte<gt> <lt>byte<gt>
* - <lt>byte<gt> <lt>byte<gt> <lt>byte<gt>
* <lt>byte<gt> <lt>byte<gt> <lt>byte<gt> }
*
* @returns
*
* Returns zero if <p ptszGUID> is not a valid GUID.
*
*
* @comm
*
* Stolen from TweakUI.
*
*****************************************************************************/
BOOL
ParseGUID(LPGUID pguid, LPCTSTR ptsz)
{
if(lstrlen(ptsz) == ctchGuid - 1 && *ptsz == TEXT('{'))
{
ptsz++;
ptsz = _ParseHex(ptsz, (LPBYTE *)&pguid, 4, TEXT('-'));
ptsz = _ParseHex(ptsz, (LPBYTE *)&pguid, 2, TEXT('-'));
ptsz = _ParseHex(ptsz, (LPBYTE *)&pguid, 2, TEXT('-'));
ptsz = _ParseHex(ptsz, (LPBYTE *)&pguid, 1, 0 );
ptsz = _ParseHex(ptsz, (LPBYTE *)&pguid, 1, TEXT('-'));
ptsz = _ParseHex(ptsz, (LPBYTE *)&pguid, 1, 0 );
ptsz = _ParseHex(ptsz, (LPBYTE *)&pguid, 1, 0 );
ptsz = _ParseHex(ptsz, (LPBYTE *)&pguid, 1, 0 );
ptsz = _ParseHex(ptsz, (LPBYTE *)&pguid, 1, 0 );
ptsz = _ParseHex(ptsz, (LPBYTE *)&pguid, 1, 0 );
ptsz = _ParseHex(ptsz, (LPBYTE *)&pguid, 1, TEXT('}'));
return (BOOL)(UINT_PTR)ptsz;
} else
{
return 0;
}
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func LONG | RegQueryString |
*
* Wrapper for <f RegQueryValueEx> that reads a
* string value from the registry. An annoying quirk
* is that on Windows NT, the returned string might
* not end in a null terminator, so we might need to add
* one manually.
*
* @parm IN HKEY | hk |
*
* Parent registry key.
*
* @parm LPCTSTR | ptszValue |
*
* Value name.
*
* @parm LPTSTR | ptsz |
*
* Output buffer.
*
* @parm DWORD | ctchBuf |
*
* Size of output buffer.
*
* @returns
*
* Registry error code.
*
*****************************************************************************/
LONG
RegQueryString(HKEY hk, LPCTSTR ptszValue, LPTSTR ptszBuf, DWORD ctchBuf)
{
LONG lRc;
DWORD reg;
#ifdef UNICODE
DWORD cb;
/*
* NT quirk: Non-null terminated strings can exist.
*/
cb = cbCtch(ctchBuf);
lRc = RegQueryValueEx(hk, ptszValue, 0, &reg, (LPBYTE)(PV)ptszBuf, &cb);
if(lRc == ERROR_SUCCESS)
{
if(reg == REG_SZ)
{
/*
* Check the last character. If it is not NULL, then
* append a NULL if there is room.
*/
DWORD ctch = ctchCb(cb);
if(ctch == 0)
{
ptszBuf[ctch] = TEXT('\0');
} else if(ptszBuf[ctch-1] != TEXT('\0'))
{
if(ctch < ctchBuf)
{
ptszBuf[ctch] = TEXT('\0');
} else
{
lRc = ERROR_MORE_DATA;
}
}
} else
{
lRc = ERROR_INVALID_DATA;
}
}
#else
/*
* This code is executed only on Win95, so we don't have to worry
* about the NT quirk.
*/
lRc = RegQueryValueEx(hk, ptszValue, 0, &reg, (LPBYTE)(PV)ptszBuf, &ctchBuf);
if(lRc == ERROR_SUCCESS && reg != REG_SZ)
{
lRc = ERROR_INVALID_DATA;
}
#endif
return lRc;
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | _CreateInstance |
*
* Worker function for <f DICoCreateInstance>.
*
* @parm REFCLSID | rclsid |
*
* The <t CLSID> to create.
*
* @parm LPCTSTR | ptszDll |
*
* The name of the DLL to load.
*
* @parm LPUNKNOWN | punkOuter |
*
* Controlling unknown for aggregation.
*
* @parm RIID | riid |
*
* Interface to obtain.
*
* @parm PPV | ppvOut |
*
* Receives a pointer to the created object if successful.
*
* @parm HINSTANCE * | phinst |
*
* Receives the instance handle of the in-proc DLL that was
* loaded. <f FreeLibrary> this DLL when you are finished
* with the object.
*
* Note that since we don't implement a binder, this means
* that you cannot give the returned pointer away to anybody
* you don't control; otherwise, you won't know when to
* free the DLL.
*
* @returns
*
* Standard OLE status code.
*
*****************************************************************************/
HRESULT
_CreateInprocObject(BOOL bInstance, REFCLSID rclsid, LPCTSTR ptszDll, LPUNKNOWN punkOuter,
REFIID riid, LPVOID *ppvOut, HINSTANCE *phinst)
{
HRESULT hres;
HINSTANCE hinst;
hinst = LoadLibrary(ptszDll);
if (hinst) {
LPFNGETCLASSOBJECT DllGetClassObject;
DllGetClassObject = (LPFNGETCLASSOBJECT)
GetProcAddress(hinst, "DllGetClassObject");
if (DllGetClassObject) {
IClassFactory *pcf;
if (bInstance)
hres = DllGetClassObject(rclsid, IID_IClassFactory, (LPVOID *)&pcf);
else
{
hres = DllGetClassObject(rclsid, riid, ppvOut);
if (FAILED(hres))
*ppvOut = NULL;
}
if (SUCCEEDED(hres) && bInstance) {
hres = pcf->CreateInstance(punkOuter, riid, ppvOut);
pcf->Release();
/*
* People forget to adhere to
* the OLE spec, which requires that *ppvOut be
* set to zero on failure.
*/
if (FAILED(hres)) {
/* if (*ppvOut) {
RPF("ERROR! CoCreateInstance: %s forgot to zero "
"out *ppvOut on failure path", ptszDll);
}*/
*ppvOut = 0;
}
}
} else {
/*
* DLL does not export GetClassObject.
*/
hres = REGDB_E_CLASSNOTREG;
}
if (SUCCEEDED(hres)) {
*phinst = hinst;
} else {
FreeLibrary(hinst);
}
} else {
/*
* DLL does not exist.
*/
hres = REGDB_E_CLASSNOTREG;
}
return hres;
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | DICoCreateInstance |
*
* Private version of CoCreateInstance that doesn't use OLE.
*
* @parm LPTSTR | ptszClsid |
*
* The string version of the <t CLSID> to create.
*
* @parm LPUNKNOWN | punkOuter |
*
* Controlling unknown for aggregation.
*
* @parm RIID | riid |
*
* Interface to obtain.
*
* @parm PPV | ppvOut |
*
* Receives a pointer to the created object if successful.
*
* @parm HINSTANCE * | phinst |
*
* Receives the instance handle of the in-proc DLL that was
* loaded. <f FreeLibrary> this DLL when you are finished
* with the object.
*
* Note that since we don't implement a binder, this means
* that you cannot give the returned pointer away to anybody
* you don't control; otherwise, you won't know when to
* free the DLL.
*
* @returns
*
* Standard OLE status code.
*
*****************************************************************************/
STDMETHODIMP
CreateInprocObject(BOOL bInstance, LPCTSTR ptszClsid, LPUNKNOWN punkOuter,
REFIID riid, LPVOID *ppvOut, HINSTANCE *phinst)
{
HRESULT hres;
CLSID clsid;
*ppvOut = 0;
*phinst = 0;
if (ParseGUID(&clsid, ptszClsid)) {
HKEY hk;
LONG lRc;
TCHAR tszKey[ctchGuid + 40]; /* 40 is more than enough */
/*
* Look up the CLSID in HKEY_CLASSES_ROOT.
*/
wsprintf(tszKey, TEXT("CLSID\\%s\\InProcServer32"), ptszClsid);
lRc = RegOpenKeyEx(HKEY_CLASSES_ROOT, tszKey, 0,
KEY_QUERY_VALUE, &hk);
if (lRc == ERROR_SUCCESS) {
TCHAR tszDll[MAX_PATH];
DWORD cb;
cb = cbX(tszDll);
lRc = RegQueryValue(hk, 0, tszDll, (PLONG)&cb);
if (lRc == ERROR_SUCCESS) {
TCHAR tszModel[20]; /* more than enough */
lRc = RegQueryString(hk, TEXT("ThreadingModel"),
tszModel, cA(tszModel));
if (lRc == ERROR_SUCCESS &&
((lstrcmpi(tszModel, TEXT("Both"))==0x0) ||
(lstrcmpi(tszModel, TEXT("Free"))==0x0))) {
hres = _CreateInprocObject(bInstance, clsid, tszDll, punkOuter,
riid, ppvOut, phinst);
} else {
/*
* No threading model or bad threading model.
*/
hres = REGDB_E_CLASSNOTREG;
}
} else {
/*
* No InprocServer32.
*/
hres = REGDB_E_CLASSNOTREG;
}
RegCloseKey(hk);
} else {
/*
* CLSID not registered.
*/
hres = REGDB_E_CLASSNOTREG;
}
} else {
/*
* Invalid CLSID string.
*/
hres = REGDB_E_CLASSNOTREG;
}
return hres;
}
HRESULT
PrivCreateInstance(REFCLSID ptszClsid, LPUNKNOWN punkOuter, DWORD dwClsContext,
REFIID riid, LPVOID *ppvOut, HINSTANCE *phinst)
{
if (dwClsContext != CLSCTX_INPROC_SERVER || phinst == NULL)
return E_INVALIDARG;
return CreateInprocObject(TRUE, GUIDSTR(ptszClsid), punkOuter, riid, ppvOut, phinst);
}
HRESULT
PrivGetClassObject(REFCLSID ptszClsid, DWORD dwClsContext, LPVOID pReserved,
REFIID riid, LPVOID *ppvOut, HINSTANCE *phinst)
{
if (dwClsContext != CLSCTX_INPROC_SERVER || pReserved != NULL || phinst == NULL)
return E_INVALIDARG;
return CreateInprocObject(FALSE, GUIDSTR(ptszClsid), NULL, riid, ppvOut, phinst);
}

View File

@@ -0,0 +1,14 @@
#ifndef __PRIVCOM_H__
#define __PRIVCOM_H__
HRESULT
PrivCreateInstance(REFCLSID ptszClsid, LPUNKNOWN punkOuter, DWORD dwClsContext,
REFIID riid, LPVOID *ppvOut, HINSTANCE *phinst);
HRESULT
PrivGetClassObject(REFCLSID ptszClsid, DWORD dwClsContext, LPVOID pReserved,
REFIID riid, LPVOID *ppvOut, HINSTANCE *phinst);
#endif //__PRIVCOM_H__

View File

@@ -0,0 +1,45 @@
//-----------------------------------------------------------------------------
//
// Sample Name: DIConfig
//
// Copyright (c) 2000 Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
Description
===========
The DIConfig code demonstrates the implementation of a configuration
user interface based upon the DirectInput Mapper technology. This
sample code is *very* complex, and is intended to be taken as a
reference implementation more than a learning tool.
Path
====
Source: DXSDK\Samples\Multimedia\DInput\DIConfig
Executable: DXSDK\Samples\Multimedia\DInput\Bin
User's Guide
============
Not applicable. This is not a sample usable by end-users.
Programming Notes
=================
This code generates a binary called diconfig.dll, which contains all
of the functionality used in the default Mapper UI. This code is very
complex and is intended as a reference implementation of a
DirectInput-based configuration user interface.
Please review the comments within the code itself for documentation
on this sample. The following major features are supported in this
sample:
 Display of device images.
 Display and reconfiguration of devices.
 Support for multiple device views, to illustrate alternate viewing
angles.
 Support for control activation overlays.
 Use of the GetImageInfo method.
 Device "ownership" for multi-user applications (same machine).
 Persistence of user settings by way of SetActionMap.

View File

@@ -0,0 +1,314 @@
//-----------------------------------------------------------------------------
// File: registry.cpp
//
// Desc: Contains COM register and unregister functions for the UI.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
////////////////////////////////////////////////////////
//
// Internal helper functions prototypes
//
// Set the given key and its value.
BOOL setKeyAndValue(LPCTSTR pszPath,
LPCTSTR szSubkey,
LPCTSTR szValue);
// Set named value.
BOOL setNamedValue(LPCTSTR pszPath,
LPCTSTR szSubkey,
LPCTSTR szKeyName,
LPCTSTR szValue);
// Convert a CLSID into a char string.
void CLSIDtochar(const CLSID& clsid,
LPTSTR szCLSID,
int length);
// Delete szKeyChild and all of its descendents.
LONG recursiveDeleteKey(HKEY hKeyParent, LPCTSTR szKeyChild);
////////////////////////////////////////////////////////
//
// Constants
//
// Size of a CLSID as a string
const int CLSID_STRING_SIZE = 39 ;
/////////////////////////////////////////////////////////
//
// Public function implementation
//
//
// Register the component in the registry.
//
HRESULT RegisterServer(HMODULE hModule, // DLL module handle
const CLSID& clsid, // Class ID
LPCTSTR szFriendlyName, // Friendly Name
LPCTSTR szVerIndProgID, // Programmatic
LPCTSTR szProgID) // IDs
{
// Get server location.
TCHAR szModule[512];
DWORD dwResult =
::GetModuleFileName(hModule,
szModule,
sizeof(szModule)/sizeof(TCHAR));
if (!dwResult) return E_FAIL;
// Convert the CLSID into a char.
TCHAR szCLSID[CLSID_STRING_SIZE];
CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)/sizeof(TCHAR));
// Build the key CLSID\\{...}
TCHAR szKey[64];
_tcscpy(szKey, _T("CLSID\\"));
_tcscat(szKey, szCLSID);
TCHAR szThreadKey[64];
_tcscpy(szThreadKey, szKey);
_tcscat(szThreadKey, _T("\\InProcServer32"));
// Add the CLSID to the registry.
setKeyAndValue(szKey, NULL, szFriendlyName);
// Add the server filename subkey under the CLSID key.
setKeyAndValue(szKey, _T("InProcServer32"), szModule);
// Add the threading model subkey under the CLSID key
setNamedValue(szKey, _T("InProcServer32"), _T("ThreadingModel"), _T("Both"));
// Add the ProgID subkey under the CLSID key.
setKeyAndValue(szKey, _T("ProgID"), szProgID);
// Add the version-independent ProgID subkey under CLSID key.
setKeyAndValue(szKey, _T("VersionIndependentProgID"),
szVerIndProgID);
// Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
setKeyAndValue(szVerIndProgID, NULL, szFriendlyName);
setKeyAndValue(szVerIndProgID, _T("CLSID"), szCLSID);
setKeyAndValue(szVerIndProgID, _T("CurVer"), szProgID);
// Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
setKeyAndValue(szProgID, NULL, szFriendlyName);
setKeyAndValue(szProgID, _T("CLSID"), szCLSID);
return S_OK;
}
//
// Remove the component from the registry.
//
LONG UnregisterServer(const CLSID& clsid, // Class ID
LPCTSTR szVerIndProgID, // Programmatic
LPCTSTR szProgID) // IDs
{
// Convert the CLSID into a char.
TCHAR szCLSID[CLSID_STRING_SIZE];
CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)/sizeof(TCHAR));
// Build the key CLSID\\{...}
TCHAR szKey[64];
_tcscpy(szKey, _T("CLSID\\"));
_tcscat(szKey, szCLSID);
// Delete the CLSID Key - CLSID\{...}
LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey);
assert((lResult == ERROR_SUCCESS) ||
(lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.
// Delete the version-independent ProgID Key.
lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID);
assert((lResult == ERROR_SUCCESS) ||
(lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.
// Delete the ProgID key.
lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID);
assert((lResult == ERROR_SUCCESS) ||
(lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.
return S_OK;
}
///////////////////////////////////////////////////////////
//
// Internal helper functions
//
// Convert a CLSID to a char string.
void CLSIDtochar(const CLSID& clsid,
LPTSTR szCLSID,
int length)
{
if (length < CLSID_STRING_SIZE)
return;
// Get CLSID
LPOLESTR wszCLSID = NULL;
HRESULT hr = StringFromCLSID(clsid, &wszCLSID);
assert(SUCCEEDED(hr));
if (!wszCLSID) return;
#ifdef _UNICODE
_tcsncpy(szCLSID, wszCLSID, length);
#else
// Covert from wide characters to non-wide.
wcstombs(szCLSID, wszCLSID, length);
#endif
// Free memory.
CoTaskMemFree(wszCLSID);
}
//
// Delete a key and all of its descendents.
//
LONG recursiveDeleteKey(HKEY hKeyParent, // Parent of key to delete
LPCTSTR lpszKeyChild) // Key to delete
{
// Open the child.
HKEY hKeyChild;
LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0,
KEY_ALL_ACCESS, &hKeyChild);
if (lRes != ERROR_SUCCESS)
{
return lRes;
}
// Enumerate all of the decendents of this child.
FILETIME time;
TCHAR szBuffer[256];
DWORD dwSize = 256;
while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,
NULL, NULL, &time) == S_OK)
{
// Delete the decendents of this child.
lRes = recursiveDeleteKey(hKeyChild, szBuffer);
if (lRes != ERROR_SUCCESS)
{
// Cleanup before exiting.
RegCloseKey(hKeyChild);
return lRes;
}
dwSize = 256;
}
// Close the child.
RegCloseKey(hKeyChild);
// Delete this child.
return RegDeleteKey(hKeyParent, lpszKeyChild);
}
//
// Create a key and set its value.
//
BOOL setKeyAndValue(LPCTSTR szKey,
LPCTSTR szSubkey,
LPCTSTR szValue)
{
HKEY hKey;
LPTSTR szKeyBuf;
if (szKey == NULL) return FALSE;
// Allocate space
szKeyBuf = new TCHAR[lstrlen(szKey) + lstrlen(szSubkey) + 2];
if (!szKeyBuf) return FALSE;
// Copy keyname into buffer.
_tcscpy(szKeyBuf, szKey);
// Add subkey name to buffer.
if (szSubkey != NULL)
{
_tcscat(szKeyBuf, _T("\\"));
_tcscat(szKeyBuf, szSubkey );
}
// Create and open key and subkey.
long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT,
szKeyBuf,
0, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL,
&hKey, NULL);
if (lResult != ERROR_SUCCESS)
{
delete[] szKeyBuf;
return FALSE;
}
// Set the Value.
if (szValue != NULL)
{
RegSetValueEx(hKey, NULL, 0, REG_SZ,
(BYTE *)szValue,
sizeof(TCHAR) * ( _tcslen(szValue)+1) );
}
RegCloseKey(hKey);
delete[] szKeyBuf;
return TRUE;
}
//
// Create a key and set its value.
BOOL setNamedValue(LPCTSTR szKey,
LPCTSTR szSubkey,
LPCTSTR szKeyName,
LPCTSTR szValue)
{
HKEY hKey;
LPTSTR szKeyBuf;
if (szKey == NULL) return FALSE;
// Allocate space
szKeyBuf = new TCHAR[lstrlen(szKey) + lstrlen(szSubkey) + 2];
if (!szKeyBuf) return FALSE;
// Copy keyname into buffer.
_tcscpy(szKeyBuf, szKey);
// Add subkey name to buffer.
if (szSubkey != NULL)
{
_tcscat(szKeyBuf, _T("\\"));
_tcscat(szKeyBuf, szSubkey );
}
// Create and open key and subkey.
long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT,
szKeyBuf,
0, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL,
&hKey, NULL);
if (lResult != ERROR_SUCCESS)
{
delete[] szKeyBuf;
return FALSE ;
}
// Set the Value.
if (szValue != NULL)
{
RegSetValueEx(hKey, szKeyName, 0, REG_SZ,
(BYTE *)szValue,
sizeof(TCHAR) * ( _tcslen(szValue)+1) );
}
RegCloseKey(hKey);
delete[] szKeyBuf;
return TRUE;
}

View File

@@ -0,0 +1,26 @@
//-----------------------------------------------------------------------------
// File: registry.h
//
// Desc: Contains COM register and unregister functions for the UI.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __Registry_H__
#define __Registry_H__
// This function will register a component in the Registry.
// The component calls this function from its DllRegisterServer function.
HRESULT RegisterServer(HMODULE hModule,
const CLSID& clsid,
LPCTSTR szFriendlyName,
LPCTSTR szVerIndProgID,
LPCTSTR szProgID) ;
// This function will unregister a component. Components
// call this function from their DllUnregisterServer function.
HRESULT UnregisterServer(const CLSID& clsid,
LPCTSTR szVerIndProgID,
LPCTSTR szProgID) ;
#endif

View File

@@ -0,0 +1,155 @@
#include "common.hpp"
CSelControlDlg::CSelControlDlg(CDeviceView &view, CDeviceControl &control, BOOL bReselect, DWORD dwOfs, const DIDEVICEINSTANCEW &didi) :
m_bReselect(bReselect), m_dwOfs(dwOfs), m_didi(didi),
m_view(view), m_control(control), m_bAssigned(FALSE), m_bNoItems(TRUE)
{
}
CSelControlDlg::~CSelControlDlg()
{
}
int CSelControlDlg::DoModal(HWND hParent)
{
return CFlexWnd::DoModal(hParent, IDD_SELCONTROLDLG, g_hModule);
}
BOOL CALLBACK AddItem(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef)
{
if (pvRef == NULL || lpddoi == NULL)
return DIENUM_CONTINUE;
return ((CSelControlDlg *)pvRef)->AddItem(*lpddoi);
}
BOOL CSelControlDlg::AddItem(const DIDEVICEOBJECTINSTANCE &doi)
{
if (m_hList == NULL || m_view.DoesCalloutOtherThanSpecifiedExistForOffset(&m_control, doi.dwType))
return DIENUM_CONTINUE;
LRESULT i = SendMessage(m_hList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR)doi.tszName);
if (i == LB_ERR || i == LB_ERRSPACE)
return DIENUM_CONTINUE;
m_bNoItems = FALSE;
i = SendMessage(m_hList, LB_SETITEMDATA, (WPARAM)i, (LPARAM)doi.dwType);
return DIENUM_CONTINUE;
}
void CSelControlDlg::OnInit()
{
m_hList = GetDlgItem(m_hWnd, IDC_LIST);
if (m_hList == NULL)
return;
LPDIRECTINPUTDEVICE8 pDID = NULL;
LPDIRECTINPUT8 pDI = NULL;
DWORD dwVer = DIRECTINPUT_VERSION;
HRESULT hr;
if (FAILED(hr = DirectInput8Create(g_hModule, dwVer, IID_IDirectInput8, (LPVOID*)&pDI, NULL)))
return;
if (FAILED(hr = pDI->CreateDevice(m_didi.guidInstance, &pDID, NULL)))
{
pDID = NULL;
return;
}
pDI->Release();
pDI = NULL;
if (FAILED(hr = pDID->EnumObjects(::AddItem, this, DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV)))
return;
pDID->Release();
pDID = NULL;
if (m_bNoItems)
{
EndDialog(SCDR_NOFREE);
return;
}
// indicate callout offset assignment...
int i = -1;
if (m_control.IsOffsetAssigned())
{
BOOL m_bAssigned = TRUE;
m_dwOfs = m_control.GetOffset();
i = GetItemWithOffset(m_dwOfs);
}
SendMessage(m_hList, LB_SETCURSEL, (WPARAM)i, 0);
}
LRESULT CSelControlDlg::OnCommand(WORD wNotifyCode, WORD wID, HWND hWnd)
{
switch (wNotifyCode)
{
case LBN_SELCHANGE:
{
if (m_hList == NULL || m_hList != hWnd)
break;
LRESULT lr = SendMessage(m_hList, LB_GETCURSEL, 0, 0);
if (lr == LB_ERR)
break;
lr = SendMessage(m_hList, LB_GETITEMDATA, (WPARAM)lr, 0);
if (lr == LB_ERR)
break;
m_dwOfs = (DWORD)lr;
m_bAssigned = TRUE;
break;
}
case BN_CLICKED:
switch (wID)
{
case IDOK:
if (m_bAssigned)
EndDialog(SCDR_OK);
else
MessageBox(m_hWnd, TEXT("You must either select a control for this callout or click cancel."), TEXT("Select a Control"), MB_OK);
break;
case IDCANCEL:
EndDialog(SCDR_CANCEL);
break;
}
break;
}
return 0;
}
int CSelControlDlg::GetItemWithOffset(DWORD dwOfs)
{
if (m_hList == NULL)
return -1;
LRESULT lr = SendMessage(m_hList, LB_GETCOUNT, 0, 0);
if (lr == LB_ERR)
return -1;
int n = int(lr);
if (n < 1)
return -1;
for (int i = 0; i < n; i++)
{
lr = SendMessage(m_hList, LB_GETITEMDATA, (WPARAM)i, 0);
if (lr == LB_ERR)
continue;
if ((DWORD)lr == dwOfs)
return i;
}
return -1;
}

View File

@@ -0,0 +1,53 @@
#ifdef FORWARD_DECLS
class CSelControlDlg;
#else // FORWARD_DECLS
#ifndef __SELCONTROLDLG_H__
#define __SELCONTROLDLG_H__
enum {
SCDR_OK = 1,
SCDR_CANCEL,
SCDR_NOFREE,
};
class CSelControlDlg : public CFlexWnd
{
public:
CSelControlDlg(CDeviceView &view, CDeviceControl &control, BOOL bReselect, DWORD dwOfs, const DIDEVICEINSTANCEW &didi);
~CSelControlDlg();
int DoModal(HWND hParent);
DWORD GetOffset() {return m_dwOfs;}
protected:
virtual void OnInit();
virtual LRESULT OnCommand(WORD wNotifyCode, WORD wID, HWND hWnd);
virtual BOOL OnEraseBkgnd(HDC) {return FALSE;}
private:
BOOL m_bReselect;
DWORD m_dwOfs;
BOOL m_bAssigned;
const DIDEVICEINSTANCEW &m_didi;
friend BOOL CALLBACK AddItem(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef);
BOOL AddItem(const DIDEVICEOBJECTINSTANCE &doi);
CDeviceControl &m_control;
CDeviceView &m_view;
HWND m_hList;
BOOL m_bNoItems;
int GetItemWithOffset(DWORD dwOfs);
};
#endif //__SELCONTROLDLG_H__
#endif // FORWARD_DECLS

View File

@@ -0,0 +1,221 @@
//-----------------------------------------------------------------------------
// File: uielements.h
//
// Desc: Defines various UI element definitions used throughout the UI.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __DEFINE_ELEMENT_STRUCTURES__
#ifndef __UIELEMENTS_H_ENUMS__
#define __UIELEMENTS_H_ENUMS__
enum UIELEMENT {
UIE_VOID,
//
UIE_TAB,
UIE_TABARROW,
UIE_SELTAB,
UIE_BUTTON,
UIE_DEFBUTTON,
UIE_BORDER,
UIE_VIEWSEL,
UIE_DEVOBJ,
UIE_GLYPH,
UIE_CALLOUT,
UIE_CALLOUTHIGH,
UIE_CALLOUTSHADOW,
UIE_CALLOUTMAX,
UIE_CALLOUTALIGN,
UIE_VIEWBORDER,
UIE_SBTRACK,
UIE_SBTHUMB,
UIE_SBBUTTON,
UIE_USERNAMES,
UIE_USERNAMESEL,
UIE_ACTION,
UIE_ACTIONLABEL,
UIE_PICERRORTEXT,
UIE_PICCUSTOMTEXT,
UIE_PICCUSTOM2TEXT,
UIE_ERRORHEADER,
UIE_ERRORMESSAGE,
};
enum UIFONT {
UIF_VOID,
UIF_LAST,
//
UIF_FRAME,
UIF_DEVOBJ,
UIF_CALLOUT,
UIF_ACTION,
UIF_ACTIONLABEL,
UIF_INFO,
UIF_VIEWSEL,
UIF_PICERROR,
UIF_PICCUSTOM,
UIF_PICCUSTOM2,
UIF_ERRORHEADER,
UIF_ERRORMESSAGE,
};
enum UIBRUSH {
UIB_VOID,
UIB_LAST,
UIB_NULL,
//
UIB_BLACK,
UIB_AREAFILL,
UIB_HIGHLIGHTFILL,
UIB_SB,
};
enum UIPEN {
UIP_VOID,
UIP_LAST,
UIP_NULL,
//
UIP_BORDER,
UIP_BLACK,
UIP_AREAFILL,
UIP_TEXTFORE,
UIP_VIEWSELGRID,
UIP_CALLOUTLINE,
UIP_CALLOUTHIGHLIGHT,
UIP_CALLOUTMAX,
UIP_CALLOUTALIGN,
UIP_VIEWBORDER,
UIP_SELTHUMB,
};
enum UICOLOR {
UIC_VOID,
UIC_LAST,
UIC_NULL,
//
UIC_BLACK,
UIC_WHITE,
UIC_RED,
//
UIC_TEXTFORE,
UIC_TEXTHIGHLIGHT,
UIC_CALLOUTLINE,
UIC_CALLOUTHIGHLIGHT,
UIC_BORDER,
UIC_CONTROLFILL,
UIC_HIGHLIGHTFILL,
UIC_AREAFILL,
//
UIC_PICERRORTEXT,
};
#endif //__UIELEMENTS_H_ENUMS__
#else // __DEFINE_ELEMENT_STRUCTURES__
#ifndef __UIELEMENTS_H_TABLES__
#define __UIELEMENTS_H_TABLES__
static const UIELEMENTINFO uielement[] = {
{UIE_TAB, UIF_FRAME, UIB_NULL, UIP_BORDER, UIC_BORDER, UIC_NULL},
{UIE_TABARROW, UIF_LAST, UIB_BLACK, UIP_BORDER, UIC_LAST, UIC_LAST},
{UIE_SELTAB, UIF_FRAME, UIB_HIGHLIGHTFILL, UIP_BORDER, UIC_BORDER, UIC_NULL},
{UIE_BUTTON, UIF_FRAME, UIB_NULL, UIP_AREAFILL, UIC_AREAFILL, UIC_NULL},
{UIE_DEFBUTTON, UIF_FRAME, UIB_HIGHLIGHTFILL, UIP_BORDER, UIC_BORDER, UIC_NULL},
{UIE_BORDER, UIF_LAST, UIB_NULL, UIP_BORDER, UIC_LAST, UIC_LAST},
{UIE_VIEWSEL, UIF_VIEWSEL, UIB_NULL, UIP_NULL, UIC_TEXTFORE, UIC_NULL},
{UIE_DEVOBJ, UIF_DEVOBJ, UIB_LAST, UIP_LAST, UIC_TEXTFORE, UIC_BLACK},
{UIE_GLYPH, UIF_LAST, UIB_LAST, UIP_LAST, UIC_TEXTFORE, UIC_NULL},
{UIE_CALLOUT, UIF_CALLOUT, UIB_AREAFILL, UIP_CALLOUTLINE, UIC_TEXTFORE, UIC_AREAFILL},
{UIE_CALLOUTHIGH, UIF_CALLOUT, UIB_AREAFILL, UIP_CALLOUTHIGHLIGHT, UIC_TEXTHIGHLIGHT, UIC_AREAFILL},
{UIE_CALLOUTSHADOW, UIF_LAST, UIB_LAST, UIP_AREAFILL, UIC_LAST, UIC_LAST},
{UIE_CALLOUTMAX, UIF_LAST, UIB_NULL, UIP_CALLOUTMAX, UIC_LAST, UIC_NULL},
{UIE_CALLOUTALIGN, UIF_LAST, UIB_LAST, UIP_CALLOUTALIGN, UIC_LAST, UIC_LAST},
{UIE_VIEWBORDER, UIF_LAST, UIB_NULL, UIP_VIEWBORDER, UIC_LAST, UIC_NULL},
{UIE_SBTRACK, UIF_LAST, UIB_AREAFILL, UIP_NULL, UIC_LAST, UIC_LAST},
{UIE_SBTHUMB, UIF_LAST, UIB_SB, UIP_NULL, UIC_LAST, UIC_LAST},
{UIE_SBBUTTON, UIF_LAST, UIB_SB, UIP_BORDER, UIC_LAST, UIC_LAST},
{UIE_USERNAMES, UIF_LAST, UIB_SB, UIP_BORDER, UIC_TEXTFORE, UIC_AREAFILL},
{UIE_USERNAMESEL, UIF_LAST, UIB_LAST, UIP_LAST, UIC_AREAFILL, UIC_TEXTFORE},
{UIE_ACTION, UIF_ACTION, UIB_LAST, UIP_LAST, UIC_TEXTFORE, UIC_NULL},
{UIE_ACTIONLABEL, UIF_ACTIONLABEL, UIB_LAST, UIP_LAST, UIC_TEXTFORE, UIC_NULL},
{UIE_PICERRORTEXT, UIF_PICERROR, UIB_LAST, UIP_LAST, UIC_PICERRORTEXT, UIC_BLACK},
{UIE_PICCUSTOMTEXT, UIF_PICCUSTOM, UIB_LAST, UIP_LAST, UIC_PICERRORTEXT, UIC_BLACK},
{UIE_PICCUSTOM2TEXT,UIF_PICCUSTOM2, UIB_LAST, UIP_LAST, UIC_PICERRORTEXT, UIC_BLACK},
{UIE_ERRORHEADER, UIF_ERRORHEADER, UIB_LAST, UIP_LAST, UIC_PICERRORTEXT, UIC_BLACK},
{UIE_ERRORMESSAGE, UIF_ERRORMESSAGE, UIB_LAST, UIP_LAST, UIC_PICERRORTEXT, UIC_BLACK},
};
static const UIFONTINFO uifont[] = {
{UIF_FRAME, _T("System"), 9, TRUE, NULL},
{UIF_DEVOBJ, _T("System"), 10, TRUE, NULL},
{UIF_CALLOUT, _T("System"), 10, FALSE, NULL},
{UIF_ACTION, _T("System"), 8, FALSE, NULL},
{UIF_ACTIONLABEL, _T("System"), 12, TRUE, NULL},
{UIF_INFO, _T("System"), 9, TRUE, NULL},
{UIF_VIEWSEL, _T("System"), 8, TRUE, NULL},
{UIF_PICERROR, _T("Arial"), 30, TRUE, NULL},
{UIF_PICCUSTOM, _T("Arial"), 30, TRUE, NULL},
{UIF_PICCUSTOM2, _T("Arial"), 15, TRUE, NULL},
{UIF_ERRORHEADER, _T("Arial"), 60, TRUE, NULL},
{UIF_ERRORMESSAGE, _T("Arial"), 30, TRUE, NULL},
};
static const UIBRUSHINFO uibrush[] = {
{UIB_BLACK, UIC_BLACK, NULL, NULL},
{UIB_AREAFILL, UIC_AREAFILL, NULL, NULL},
{UIB_HIGHLIGHTFILL, UIC_HIGHLIGHTFILL, NULL, NULL},
{UIB_SB, UIC_CONTROLFILL, NULL, NULL},
};
static const UIPENINFO uipen[] = {
{UIP_BORDER, PS_SOLID, 1, UIC_BORDER, NULL},
{UIP_BLACK, PS_SOLID, 1, UIC_BLACK, NULL},
{UIP_AREAFILL, PS_SOLID, 1, UIC_AREAFILL, NULL},
{UIP_TEXTFORE, PS_SOLID, 1, UIC_TEXTFORE, NULL},
{UIP_VIEWSELGRID, PS_SOLID, 1, UIC_WHITE, NULL},
{UIP_CALLOUTLINE, PS_SOLID, 1, UIC_CALLOUTLINE, NULL},
{UIP_CALLOUTHIGHLIGHT, PS_SOLID, 1, UIC_CALLOUTHIGHLIGHT, NULL},
{UIP_CALLOUTMAX, PS_DOT, 1, UIC_WHITE, NULL},
{UIP_CALLOUTALIGN, PS_SOLID, 1, UIC_RED, NULL},
{UIP_VIEWBORDER, PS_DOT, 1, UIC_RED, NULL},
{UIP_SELTHUMB, PS_SOLID, 3, UIC_WHITE, NULL},
};
static const UICOLORINFO uicolor[] = {
{UIC_WHITE, RGB(255, 255, 255)},
{UIC_BLACK, RGB( 0, 0, 0)},
{UIC_RED, RGB(255, 0, 0)},
//
{UIC_TEXTFORE, RGB(191, 0, 0)},
{UIC_TEXTHIGHLIGHT, RGB(255, 0, 0)},
{UIC_CALLOUTLINE, RGB(191, 0, 0)},
{UIC_CALLOUTHIGHLIGHT, RGB(255, 0, 0)},
{UIC_BORDER, RGB(255, 0, 0)},
{UIC_CONTROLFILL, RGB(127, 0, 0)},
{UIC_HIGHLIGHTFILL, RGB( 0, 0, 0)},
{UIC_AREAFILL, RGB( 0, 0, 0)},
//
{UIC_PICERRORTEXT, RGB(128, 128, 128)},
};
const int NUMUIELEMENTS = sizeof(uielement) / sizeof(UIELEMENTINFO);
const int NUMUIFONTS = sizeof(uifont) / sizeof(UIFONTINFO);
const int NUMUIBRUSHES = sizeof(uibrush) / sizeof(UIBRUSHINFO);
const int NUMUIPENS = sizeof(uipen) / sizeof(UIPENINFO);
const int NUMUICOLORS = sizeof(uicolor) / sizeof(UICOLORINFO);
#endif // __UIELEMENTS_H_TABLES__
#endif //__DEFINE_ELEMENT_STRUCTURES__

View File

@@ -0,0 +1,771 @@
//-----------------------------------------------------------------------------
// File: uiglobals.cpp
//
// Desc: CUIGlobals is a class that packs and holds most information
// relevent to a UI session. Many classes make reference to
// CUIGlobals all the time.
//
// CPaintHelper encapsulates GDI calls, simplifying GDI operations.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
#define __DEFINE_ELEMENT_STRUCTURES__
#include "uielements.h"
static const GUID GUID_DIConfigAppEditLayout =
{ 0xfd4ace13, 0x7044, 0x4204, { 0x8b, 0x15, 0x9, 0x52, 0x86, 0xb1, 0x2e, 0xad } };
CUIGlobals::CUIGlobals(UIG_PARAMS_DEFINE) :
// globals...
m_hrInit(S_OK),
m_hrFinalResult(S_OK),
m_hInst(NULL),
m_lpDI(NULL),
m_dwFlags(0),
m_wszUserNames(NULL),
m_pSurface(NULL),
m_pSurface3D(NULL),
m_lpCallback(NULL),
m_pvRefData(NULL),
m_bAllowEditLayout(FALSE),
m_bUseColorSet(FALSE),
// ui...
m_pElement(NULL),
m_nElements(0),
m_pFont(NULL),
m_nFonts(0),
m_pBrush(NULL),
m_nBrushes(0),
m_pPen(NULL),
m_nPens(0),
m_pColor(NULL),
m_nColors(0)
{
tracescope(__ts,_T("CUIGlobals::CUIGlobals()\n"));
m_hrInit = Init(UIG_PARAMS_DEFINE_PASS);
}
void CUIGlobals::SetTableColor(UICOLOR uic, COLORREF c)
{
UICOLORINFO *info = GetColorInfo(uic);
assert(info != NULL);
if (info == NULL)
return;
info->rgb = c;
}
HRESULT CUIGlobals::Init(UIG_PARAMS_DEFINE)
{tracescope(__ts,_T("CUIGlobals::Init(...)\n"));
HRESULT hr = S_OK;
// get instance handle
m_hInst = (HINSTANCE)g_hModule;
if (m_hInst == NULL)
{
etrace(_T("hInst NULL\n"));
return E_FAIL;
}
// create direct input
DWORD dwVer = DIRECTINPUT_VERSION;
hr = DirectInput8Create(m_hInst, dwVer, IID_IDirectInput8W, (LPVOID *)&m_lpDI, NULL);
if (FAILED(hr) || m_lpDI == NULL)
{
m_lpDI = NULL;
etrace2(_T("Could not create DirectInput ver 0x%08x\n -> DirectInputCreateEx() returned 0x%08x\n"), dwVer, hr);
return hr;
}
// save flags
m_dwFlags = dwFlags;
#ifdef CFGUI__FORCE_NON_NULL_WSZUSERNAMES
if (wszUserNames == NULL)
wszUserNames = _T("Forced Non-NULL Username");
#endif
if (wszUserNames == NULL)
{
etrace(_T("wszUserNames was passed NULL\n"));
return E_FAIL;
}
// save user names
m_wszUserNames = DupSuperString(wszUserNames);
if (m_wszUserNames == NULL)
{
etrace(_T("Could not duplicate user names\n"));
return E_FAIL;
}
// make sure we were passed an action format
if (lpAcFor == NULL)
{
etrace(_T("lpAcFor param NULL\n"));
return E_INVALIDARG;
}
// copy the acfor to the master
hr = InitMasterAcForArray(lpAcFor, int(dwNumAcFor));
if (FAILED(hr))
{
etrace1(_T("InitMasterAcForArray() failed, returning 0x%08x\n"), hr);
return hr;
}
// get surface
if (lpSurface != NULL)
{
hr = lpSurface->QueryInterface(IID_IDirect3DSurface8, (void **)&m_pSurface3D);
if (FAILED(hr) || m_pSurface3D == NULL)
{
m_pSurface3D = NULL;
}
hr = lpSurface->QueryInterface(IID_IDirectDrawSurface, (void **)&m_pSurface);
if (FAILED(hr) || m_pSurface == NULL)
{
m_pSurface = NULL;
}
if (m_pSurface == NULL && m_pSurface3D == NULL)
etrace(_T("lpSurface was non-NULL but could not get IDirect3DSurface8 or IID_IDirectDrawSurface from it"));
}
// save callback and ref data
m_lpCallback = lpCallback;
m_pvRefData = pvRefData;
// see whether or not we're allowing edit layout mode
m_bAllowEditLayout = IsEqualGUID(RefMasterAcFor(0).guidActionMap,
GUID_DIConfigAppEditLayout);
// init a bunch of stuff necessary for painting
if (!InitColorsAndTablesAndObjects(lpDIColorSet))
return E_FAIL;
// dump info if debug
#ifdef DBG
Dump();
#endif
// return success if we got here
return S_OK;
}
BOOL CUIGlobals::InitColorsAndTablesAndObjects(LPDICOLORSET lpDIColorSet)
{tracescope(__ts,_T("CUIGlobals::InitColorsAndTablesAndObjects()\n"));
// init ui tables
if (!InitTables())
{
etrace(_T("Could not initialize tables\n"));
return FALSE;
}
// decide whether or not to use the passed colorset
if (lpDIColorSet != NULL)
{
m_ColorSet = *lpDIColorSet;
m_bUseColorSet = !IsZeroOrInvalidColorSet(m_ColorSet);
}
else
m_bUseColorSet = FALSE;
// use it, or use defaults
if (m_bUseColorSet)
{
// transfer colors from passed colorset
SetTableColor(UIC_TEXTFORE, D3DCOLOR2COLORREF(m_ColorSet.cTextFore));
SetTableColor(UIC_TEXTHIGHLIGHT, D3DCOLOR2COLORREF(m_ColorSet.cTextHighlight));
SetTableColor(UIC_CALLOUTLINE, D3DCOLOR2COLORREF(m_ColorSet.cCalloutLine));
SetTableColor(UIC_CALLOUTHIGHLIGHT, D3DCOLOR2COLORREF(m_ColorSet.cCalloutHighlight));
SetTableColor(UIC_BORDER, D3DCOLOR2COLORREF(m_ColorSet.cBorder));
SetTableColor(UIC_CONTROLFILL, D3DCOLOR2COLORREF(m_ColorSet.cControlFill));
SetTableColor(UIC_HIGHLIGHTFILL, D3DCOLOR2COLORREF(m_ColorSet.cHighlightFill));
SetTableColor(UIC_AREAFILL, D3DCOLOR2COLORREF(m_ColorSet.cAreaFill));
}
else
{
// use default colors
SetTableColor(UIC_TEXTFORE, RGB(255, 255, 255));
SetTableColor(UIC_TEXTHIGHLIGHT, RGB( 0, 255, 0));
SetTableColor(UIC_CALLOUTLINE, RGB(255, 255, 255));
SetTableColor(UIC_CALLOUTHIGHLIGHT, RGB( 0, 255, 0));
SetTableColor(UIC_BORDER, RGB(255, 255, 0));
SetTableColor(UIC_CONTROLFILL, RGB( 0, 191, 0));
SetTableColor(UIC_HIGHLIGHTFILL, RGB( 0, 0, 0));
SetTableColor(UIC_AREAFILL, RGB( 0, 0, 0));
}
// create the table objects
CreateObjects();
return TRUE;
}
CUIGlobals::~CUIGlobals()
{
tracescope(__ts,_T("CUIGlobals::~CUIGlobals()\n"));
if (m_wszUserNames != NULL)
free((LPVOID)m_wszUserNames);
m_wszUserNames = NULL;
if (m_lpDI != NULL)
m_lpDI->Release();
m_lpDI = NULL;
if (m_pSurface != NULL)
m_pSurface->Release();
m_pSurface = NULL;
if (m_pSurface3D != NULL)
m_pSurface3D->Release();
m_pSurface3D = NULL;
ClearMasterAcForArray();
ClearTables();
}
void CUIGlobals::Dump()
{
tracescope(ts, _T("UIGlobals...\n\n"));
traceHEXPTR(m_hInst);
traceHEXPTR(m_lpDI);
LPTSTR str = AllocConfigureFlagStr(m_dwFlags);
trace1(_T("m_dwFlags = %s\n"), str);
free(str);
traceSUPERSTR(m_wszUserNames);
traceHEXPTR(m_pSurface);
traceHEXPTR(m_pSurface3D);
traceHEXPTR(m_lpCallback);
traceBOOL(m_bAllowEditLayout);
{
tracescope(__csts, _T("m_ColorSet...\n"));
traceHEX(m_ColorSet.cTextFore);
traceHEX(m_ColorSet.cTextHighlight);
traceHEX(m_ColorSet.cCalloutLine);
traceHEX(m_ColorSet.cCalloutHighlight);
traceHEX(m_ColorSet.cBorder);
traceHEX(m_ColorSet.cControlFill);
traceHEX(m_ColorSet.cHighlightFill);
traceHEX(m_ColorSet.cAreaFill);
}
traceBOOL(m_bUseColorSet);
trace(_T("\n"));
TraceActionFormat(_T("Master ActionFormat 0:"), RefMasterAcFor(0));
trace(_T("\n\n"));
}
LPDIRECTINPUT8W CUIGlobals::GetDI()
{
if (m_lpDI == NULL)
return NULL;
m_lpDI->AddRef();
return m_lpDI;
}
IDirectDrawSurface *CUIGlobals::GetSurface()
{
if (m_pSurface == NULL)
return NULL;
m_pSurface->AddRef();
return m_pSurface;
}
IDirect3DSurface8 *CUIGlobals::GetSurface3D()
{
if (m_pSurface3D == NULL)
return NULL;
m_pSurface3D->AddRef();
return m_pSurface3D;
}
void CUIGlobals::DeleteObjects()
{
// make sure all our gdi objects are deleted
int i;
if (m_pFont != NULL)
for (i = 0; i < m_nFonts; i++)
{
UIFONTINFO &info = m_pFont[i];
if (info.hFont != NULL)
DeleteObject(info.hFont);
info.hFont = NULL;
}
if (m_pBrush != NULL)
for (i = 0; i < m_nBrushes; i++)
{
UIBRUSHINFO &info = m_pBrush[i];
if (info.hBrush != NULL)
DeleteObject(info.hBrush);
info.hBrush = NULL;
if (info.hPen != NULL)
DeleteObject(info.hPen);
info.hPen = NULL;
}
if (m_pPen != NULL)
for (i = 0; i < m_nPens; i++)
{
UIPENINFO &info = m_pPen[i];
if (info.hPen != NULL)
DeleteObject(info.hPen);
info.hPen = NULL;
}
}
void CUIGlobals::ClearTables()
{
// make sure all our gdi objects are deleted
DeleteObjects();
// delete the tables, null the pointers, and zero the counters
#define FREETABLE(member, memnum) \
{ \
if (member != NULL) \
delete [] member; \
member = NULL; \
memnum = 0; \
}
FREETABLE(m_pElement, m_nElements);
FREETABLE(m_pFont, m_nFonts);
FREETABLE(m_pBrush, m_nBrushes);
FREETABLE(m_pPen, m_nPens);
FREETABLE(m_pColor, m_nColors);
}
BOOL CUIGlobals::InitTables()
{
BOOL bSuccess = TRUE;
// make sure the tables have been cleared
ClearTables();
// allocate our own copies of all the tables
#define ALLOCTABLE(member, memnum, type, init, num) \
{ \
member = new type [memnum = num]; \
if (member == NULL) \
{ \
memnum = 0; \
bSuccess = FALSE; \
} \
else \
memcpy(member, init, sizeof(type) * memnum); \
}
ALLOCTABLE(m_pElement, m_nElements, UIELEMENTINFO, uielement, NUMUIELEMENTS);
ALLOCTABLE(m_pFont, m_nFonts, UIFONTINFO, uifont, NUMUIFONTS);
ALLOCTABLE(m_pBrush, m_nBrushes, UIBRUSHINFO, uibrush, NUMUIBRUSHES);
ALLOCTABLE(m_pPen, m_nPens, UIPENINFO, uipen, NUMUIPENS);
ALLOCTABLE(m_pColor, m_nColors, UICOLORINFO, uicolor, NUMUICOLORS);
return bSuccess;
}
void CUIGlobals::RecreateObjects()
{
DeleteObjects();
CreateObjects();
}
void CUIGlobals::CreateObjects()
{
// make sure all our gdi objects are created
int i;
if (m_pFont != NULL)
{
HDC hDC = GetDC(NULL);
for (i = 0; i < m_nFonts; i++)
{
UIFONTINFO &info = m_pFont[i];
if (info.hFont == NULL)
{
LOGFONT lf;
lf.lfHeight = -MulDiv(info.nPointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = info.bBold ? FW_BOLD : FW_NORMAL;
lf.lfItalic = FALSE;
lf.lfUnderline = FALSE;
lf.lfStrikeOut = FALSE;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfQuality = PROOF_QUALITY;
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
_tcscpy(lf.lfFaceName, info.lfFaceName);
info.hFont = (HGDIOBJ)CreateFontIndirect(&lf);
}
}
ReleaseDC(NULL, hDC);
}
if (m_pBrush != NULL)
for (i = 0; i < m_nBrushes; i++)
{
UIBRUSHINFO &info = m_pBrush[i];
if (info.hBrush == NULL)
info.hBrush = (HGDIOBJ)CreateSolidBrush(GetColor(info.eColor));
if (info.hPen == NULL)
info.hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, GetColor(info.eColor));
}
if (m_pPen != NULL)
for (i = 0; i < m_nPens; i++)
{
UIPENINFO &info = m_pPen[i];
if (info.hPen == NULL)
info.hPen = (HGDIOBJ)CreatePen(info.fnPenStyle, info.nWidth, GetColor(info.eColor));
}
}
#define IMPLGETINFO(Type, TYPE, Types, t) \
UI##TYPE##INFO *CUIGlobals::Get##Type##Info(UI##TYPE t) \
{ \
if (m_p##Type != NULL) \
for (int i = 0; i < m_n##Types; i++) \
if (m_p##Type[i].e##Type == t) \
return &(m_p##Type[i]); \
return NULL; \
}
IMPLGETINFO(Element, ELEMENT, Elements, e)
IMPLGETINFO(Font, FONT, Fonts, f)
IMPLGETINFO(Brush, BRUSH, Brushes, b)
IMPLGETINFO(Pen, PEN, Pens, p)
IMPLGETINFO(Color, COLOR, Colors, c)
#undef IMPLGETINFO
#define IMPLGET(T, Name, Type, TYPE, v, def, ret) \
T CUIGlobals::Get##Name(UI##TYPE ui##v) \
{ \
UI##TYPE##INFO *v = Get##Type##Info(ui##v); \
if (!v) \
return def; \
return ret; \
}
IMPLGET(HGDIOBJ, Font, Element, ELEMENT, e, NULL, GetFont(e->eFont))
IMPLGET(HGDIOBJ, Font, Font, FONT, f, NULL, f->hFont)
IMPLGET(HGDIOBJ, Brush, Element, ELEMENT, e, NULL, GetBrush(e->eBrush))
IMPLGET(HGDIOBJ, Brush, Brush, BRUSH, b, NULL, b->hBrush)
IMPLGET(HGDIOBJ, Pen, Element, ELEMENT, e, NULL, GetPen(e->ePen))
IMPLGET(HGDIOBJ, Pen, Brush, BRUSH, b, NULL, b->hPen)
IMPLGET(HGDIOBJ, Pen, Pen, PEN, p, NULL, p->hPen)
IMPLGET(COLORREF, BrushColor, Element, ELEMENT, e, RGB(255, 127, 127), GetColor(e->eBrush))
IMPLGET(COLORREF, PenColor, Element, ELEMENT, e, RGB(255, 127, 127), GetColor(e->ePen))
IMPLGET(COLORREF, TextColor, Element, ELEMENT, e, RGB(255, 127, 127), GetColor(e->eText))
IMPLGET(COLORREF, BkColor, Element, ELEMENT, e, RGB(255, 127, 127), GetColor(e->eBk))
IMPLGET(COLORREF, Color, Brush, BRUSH, b, RGB(255, 127, 127), GetColor(b->eColor))
IMPLGET(COLORREF, Color, Pen, PEN, p, RGB(255, 127, 127), GetColor(p->eColor))
IMPLGET(COLORREF, Color, Color, COLOR, c, RGB(255, 127, 127), c->rgb)
#undef IMPLGET
CPaintHelper::CPaintHelper(CUIGlobals &uig, HDC hDC) :
m_uig(uig), m_priv_hDC(hDC), m_hDC(m_priv_hDC),
m_eFont(UIF_VOID),
m_eBrush(UIB_VOID),
m_ePen(UIP_VOID),
m_eText(UIC_VOID),
m_eBk(UIC_VOID),
m_hOldFont(NULL), m_hOldBrush(NULL), m_hOldPen(NULL),
m_bOldFont(FALSE), m_bOldBrush(FALSE), m_bOldPen(FALSE)
{
if (m_hDC != NULL)
{
m_oldtextcolor = GetTextColor(m_hDC);
m_oldbkcolor = GetBkColor(m_hDC);
m_oldbkmode = GetBkMode(m_hDC);
}
}
CPaintHelper::~CPaintHelper()
{
if (m_hDC != NULL)
{
if (m_bOldFont)
SelectObject(m_hDC, m_hOldFont);
if (m_bOldBrush)
SelectObject(m_hDC, m_hOldBrush);
if (m_bOldPen)
SelectObject(m_hDC, m_hOldPen);
SetTextColor(m_hDC, m_oldtextcolor);
SetBkColor(m_hDC, m_oldbkcolor);
SetBkMode(m_hDC, m_oldbkmode);
}
}
void CPaintHelper::SetElement(UIELEMENT eElement)
{
UIELEMENTINFO *info = m_uig.GetElementInfo(eElement);
if (!info)
return;
if (info->eFont != UIF_LAST)
SetFont(info->eFont);
if (info->eBrush != UIB_LAST)
SetBrush(info->eBrush);
if (info->ePen != UIP_LAST)
SetPen(info->ePen);
SetText(info->eText, info->eBk);
}
void CPaintHelper::SetFont(UIFONT eFont)
{
if (m_eFont == eFont || eFont == UIF_LAST)
return;
HGDIOBJ hObj = m_uig.GetFont(eFont);
if (hObj == NULL)
return;
if (m_hDC != NULL)
{
HGDIOBJ hOld = NULL;
hOld = SelectObject(m_hDC, hObj);
if (!m_bOldFont)
m_hOldFont = hOld;
m_bOldFont = TRUE;
}
m_eFont = eFont;
}
void CPaintHelper::SetBrush(UIBRUSH eBrush)
{
if (m_eBrush == eBrush || eBrush == UIB_LAST)
return;
HGDIOBJ hObj = eBrush == UIB_NULL ?
GetStockObject(NULL_BRUSH) :
m_uig.GetBrush(eBrush);
if (hObj == NULL)
return;
if (m_hDC != NULL)
{
HGDIOBJ hOld = NULL;
hOld = SelectObject(m_hDC, hObj);
if (!m_bOldBrush)
m_hOldBrush = hOld;
m_bOldBrush = TRUE;
}
m_eBrush = eBrush;
}
void CPaintHelper::SetPen(UIPEN ePen)
{
if (m_ePen == ePen || ePen == UIP_LAST)
return;
HGDIOBJ hObj = ePen == UIB_NULL ?
GetStockObject(NULL_PEN) :
m_uig.GetPen(ePen);
if (hObj == NULL)
return;
if (m_hDC != NULL)
{
HGDIOBJ hOld = NULL;
hOld = SelectObject(m_hDC, hObj);
if (!m_bOldPen)
m_hOldPen = hOld;
m_bOldPen = TRUE;
}
m_ePen = ePen;
}
void CPaintHelper::SetText(UICOLOR eText, UICOLOR eBk)
{
if (m_eText != eText && eText != UIC_LAST)
{
if (m_hDC != NULL)
SetTextColor(m_hDC, m_uig.GetColor(eText));
m_eText = eText;
}
if (m_eBk != eBk && eBk != UIC_LAST)
{
if (m_hDC != NULL)
{
if (eBk == UIC_NULL)
SetBkMode(m_hDC, TRANSPARENT);
else
{
SetBkColor(m_hDC, m_uig.GetColor(eBk));
SetBkMode(m_hDC, OPAQUE);
}
}
m_eBk = eBk;
}
}
BOOL CPaintHelper::LineTo(int x, int y)
{
if (m_hDC == NULL)
return FALSE;
return ::LineTo(m_hDC, x, y);
}
BOOL CPaintHelper::MoveTo(int x, int y, SPOINT *last)
{
if (m_hDC == NULL)
return FALSE;
POINT p;
BOOL bRet = MoveToEx(m_hDC, x, y, &p);
if (last)
*last = p;
return bRet;
}
BOOL CPaintHelper::Rectangle(SRECT r, UIRECTTYPE eType)
{
// fail on no dc
if (m_hDC == NULL)
return FALSE;
// see if we lack a pen or brush (might add more checks later)
BOOL bNoPen = m_ePen == UIP_NULL;
BOOL bNoBrush = m_eBrush == UIB_NULL;
// fail if trying to do an outline without a pen
if (eType == UIR_OUTLINE && bNoPen)
return FALSE;
// fail if trying to do a solid without a brush
if (eType == UIR_SOLID && bNoBrush)
return FALSE;
// save old objects if we change anything...
HGDIOBJ hOldBrush = NULL, hOldPen = NULL;
// select a null brush if we're doing an outline and we're not already null brushed
if (eType == UIR_OUTLINE && m_eBrush != UIB_NULL)
hOldBrush = SelectObject(m_hDC, GetStockObject(NULL_BRUSH));
// select a pen the same color as the current brush if doing solid
if (eType == UIR_SOLID || m_ePen == UIP_NULL)
{
HGDIOBJ hPen = m_uig.GetPen(m_eBrush);
if (hPen == NULL)
return FALSE;
hOldPen = SelectObject(m_hDC, hPen);
}
// draw the rect
BOOL bRet = ::Rectangle(m_hDC, r.left, r.top, r.right, r.bottom);
// restore whatever changed
if (eType == UIR_OUTLINE && m_eBrush != UIB_NULL)
SelectObject(m_hDC, hOldBrush);
if (eType == UIR_SOLID || m_ePen == UIP_NULL)
SelectObject(m_hDC, hOldPen);
return bRet;
}
const DIACTIONFORMATW &CUIGlobals::RefMasterAcFor(int i)
{
assert(IsValidMasterAcForIndex(i));
return m_MasterAcForArray[i];
}
BOOL CUIGlobals::IsValidMasterAcForIndex(int i)
{
if (i < 0 || i >= m_MasterAcForArray.GetSize())
return FALSE;
return TRUE;
}
HRESULT CUIGlobals::InitMasterAcForArray(const DIACTIONFORMATW *af, int n)
{
if (n < 1)
return E_FAIL;
ClearMasterAcForArray();
m_MasterAcForArray.SetSize(n);
for (int i = 0; i < n; i++)
{
HRESULT hr = CopyActionFormat(m_MasterAcForArray[i], af[i]);
if (FAILED(hr))
{
m_MasterAcForArray.SetSize(i);
ClearMasterAcForArray();
return hr;
}
}
return S_OK;
}
void CUIGlobals::ClearMasterAcForArray()
{
int s = m_MasterAcForArray.GetSize();
for (int i = 0; i < s; i++)
CleanupActionFormatCopy(m_MasterAcForArray[i]);
m_MasterAcForArray.RemoveAll();
assert(m_MasterAcForArray.GetSize() == 0);
}
LPCWSTR CUIGlobals::GetUserName(int i)
{
return GetSubString(m_wszUserNames, i);
}
int CUIGlobals::GetNumUserNames()
{
return CountSubStrings(m_wszUserNames);
}
void CUIGlobals::SetFinalResult(HRESULT hr)
{
m_hrFinalResult = hr;
}
HRESULT CUIGlobals::GetFinalResult()
{
return m_hrFinalResult;
}
int CUIGlobals::GetUserNameIndex(LPCWSTR wsz)
{
for (int i = 0; i < GetNumUserNames(); i++)
if (_wcsicmp(wsz, GetUserName(i)) == 0)
return i;
return -1;
}

View File

@@ -0,0 +1,221 @@
//-----------------------------------------------------------------------------
// File: uiglobals.h
//
// Desc: CUIGlobals is a class that packs and holds most information
// relevent to a UI session. Many classes make reference to
// CUIGlobals all the time.
//
// CPaintHelper encapsulates GDI calls, simplifying GDI operations.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __UIGLOBALS_H__
#define __UIGLOBALS_H__
#include "uielements.h"
struct UIELEMENTINFO {
UIELEMENT eElement;
UIFONT eFont;
UIBRUSH eBrush;
UIPEN ePen;
UICOLOR eText, eBk;
};
struct UIFONTINFO {
UIFONT eFont;
LPCTSTR lfFaceName;
int nPointSize;
BOOL bBold;
HGDIOBJ hFont;
};
struct UIBRUSHINFO {
UIBRUSH eBrush;
UICOLOR eColor;
HGDIOBJ hBrush;
HGDIOBJ hPen;
};
struct UIPENINFO {
UIPEN ePen;
int fnPenStyle;
int nWidth;
UICOLOR eColor;
HGDIOBJ hPen;
};
struct UICOLORINFO {
UICOLOR eColor;
COLORREF rgb;
};
enum UIRECTTYPE {
UIR_OUTLINE,
UIR_NORMAL,
UIR_SOLID,
};
#define UIG_PARAMS_DEFINE \
DWORD dwFlags, \
LPCWSTR wszUserNames, \
DWORD dwNumAcFor, \
LPDIACTIONFORMATW lpAcFor, \
LPDICOLORSET lpDIColorSet, \
IUnknown FAR *lpSurface, \
LPDICONFIGUREDEVICESCALLBACK lpCallback, \
LPVOID pvRefData
#define UIG_PARAMS_DEFINE_PASS \
dwFlags, \
wszUserNames, \
dwNumAcFor, \
lpAcFor, \
lpDIColorSet, \
lpSurface, \
lpCallback, \
pvRefData
class CUIGlobals
{
public:
CUIGlobals(UIG_PARAMS_DEFINE);
~CUIGlobals();
// UI Variables/States/Etc...
public:
HRESULT GetInitResult() {return m_hrInit;}
HINSTANCE GetInstance() {return m_hInst;}
LPDIRECTINPUT8W GetDI();
int GetUserNameIndex(LPCWSTR);
int GetNumUserNames();
LPCWSTR GetUserName(int i);
// GetSurface should not be used as only IDirect3DSurface8 should be used. Instead, use GetSurface3D.
IDirectDrawSurface *GetSurface(); // must release when done with returned surface (it's addref'd before returned)
IDirect3DSurface8 *GetSurface3D(); // must release when done with returned surface (it's addref'd before returned)
LPDICONFIGUREDEVICESCALLBACK GetCallback() {return m_lpCallback;}
LPVOID GetRefData() {return m_pvRefData;}
DWORD GetFlags() {return m_dwFlags;}
BOOL IsFlagSet(DWORD dwFlag) {return AreFlagsSet(dwFlag);}
BOOL AreFlagsSet(DWORD dwFlags) {return (m_dwFlags & dwFlags) == dwFlags;}
BOOL InEditMode() {return IsFlagSet(DICD_EDIT);}
const DIACTIONFORMATW &RefMasterAcFor(int i);
int GetNumMasterAcFors() {return m_MasterAcForArray.GetSize();}
const DICOLORSET &GetColorSet() const { return m_ColorSet; }
void SetFinalResult(HRESULT);
HRESULT GetFinalResult();
private:
HRESULT Init(UIG_PARAMS_DEFINE);
void Dump();
HRESULT m_hrInit;
HRESULT m_hrFinalResult;
BOOL InitColorsAndTablesAndObjects(LPDICOLORSET lpDIColorSet);
BOOL IsValidUserIndex(int i);
BOOL IsValidMasterAcForIndex(int i);
HRESULT InitMasterAcForArray(const DIACTIONFORMATW *af, int n);
void ClearMasterAcForArray();
HINSTANCE m_hInst;
LPDIRECTINPUT8W m_lpDI;
DWORD m_dwFlags;
LPCWSTR m_wszUserNames;
CArray<DIACTIONFORMATW, DIACTIONFORMATW &> m_MasterAcForArray;
BOOL m_bUseColorSet;
DICOLORSET m_ColorSet;
void SetTableColor(UICOLOR, COLORREF);
IDirectDrawSurface *m_pSurface;
IDirect3DSurface8 *m_pSurface3D;
LPDICONFIGUREDEVICESCALLBACK m_lpCallback;
LPVOID m_pvRefData;
BOOL m_bAllowEditLayout;
// UI Elements...
public:
UIELEMENTINFO *GetElementInfo(UIELEMENT);
UIFONTINFO *GetFontInfo(UIFONT);
UIBRUSHINFO *GetBrushInfo(UIBRUSH);
UIPENINFO *GetPenInfo(UIPEN);
UICOLORINFO *GetColorInfo(UICOLOR);
HGDIOBJ GetFont(UIELEMENT);
HGDIOBJ GetFont(UIFONT);
HGDIOBJ GetBrush(UIELEMENT);
HGDIOBJ GetBrush(UIBRUSH);
HGDIOBJ GetPen(UIELEMENT);
HGDIOBJ GetPen(UIBRUSH);
HGDIOBJ GetPen(UIPEN);
COLORREF GetBrushColor(UIELEMENT);
COLORREF GetPenColor(UIELEMENT);
COLORREF GetTextColor(UIELEMENT);
COLORREF GetBkColor(UIELEMENT);
COLORREF GetColor(UIBRUSH);
COLORREF GetColor(UIPEN);
COLORREF GetColor(UICOLOR);
void DeleteObjects();
void CreateObjects();
void RecreateObjects();
private:
BOOL InitTables();
void ClearTables();
UIELEMENTINFO *m_pElement;
int m_nElements;
UIFONTINFO *m_pFont;
int m_nFonts;
UIBRUSHINFO *m_pBrush;
int m_nBrushes;
UIPENINFO *m_pPen;
int m_nPens;
UICOLORINFO *m_pColor;
int m_nColors;
};
class CPaintHelper
{
public:
CPaintHelper(CUIGlobals &uig, HDC hDC);
~CPaintHelper();
CUIGlobals &m_uig;
HDC &m_hDC;
void SetElement(UIELEMENT eElement);
void SetFont(UIFONT eFont);
void SetBrush(UIBRUSH eBrush);
void SetPen(UIPEN ePen);
void SetText(UICOLOR eText, UICOLOR eBk = UIC_LAST);
BOOL LineTo(SPOINT p) {return LineTo(p.x, p.y);}
BOOL LineTo(int x, int y);
BOOL MoveTo(SPOINT p, SPOINT *last = NULL) {return MoveTo(p.x, p.y, last);}
BOOL MoveTo(int x, int y, SPOINT *last = NULL);
BOOL Rectangle(SRECT r, UIRECTTYPE eType = UIR_NORMAL);
BOOL Rectangle(int l, int t, int r, int b, UIRECTTYPE eType = UIR_NORMAL)
{SRECT s(l,t,r,b); return Rectangle(s, eType);}
private:
HDC m_priv_hDC;
HGDIOBJ m_hOldFont, m_hOldBrush, m_hOldPen;
BOOL m_bOldFont, m_bOldBrush, m_bOldPen;
COLORREF m_oldtextcolor, m_oldbkcolor;
int m_oldbkmode;
UIFONT m_eFont;
UIBRUSH m_eBrush;
UIPEN m_ePen;
UICOLOR m_eText, m_eBk;
};
#endif //__UIGLOBALS_H__

View File

@@ -0,0 +1,626 @@
//-----------------------------------------------------------------------------
// File: useful.cpp
//
// Desc: Contains various utility classes and functions to help the
// UI carry its operations more easily.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include <windows.h>
#include <tchar.h>
#include <wchar.h>
#include <stdio.h>
#include <stdarg.h>
// assert include (make sure assert actually works with build)
#ifdef DBG
#undef NDEBUG
#endif
#include <assert.h>
#include "useful.h"
#include "collections.h"
/*--------- \/ stuff for collections.h \/ ---------*/
BOOL AfxIsValidAddress( const void* lp, UINT nBytes, BOOL bReadWrite)
{
// return lp != NULL;
// simple version using Win-32 APIs for pointer validation.
return (lp != NULL && !IsBadReadPtr(lp, nBytes) &&
(!bReadWrite || !IsBadWritePtr((LPVOID)lp, nBytes)));
}
CPlex* PASCAL CPlex::Create(CPlex*& pHead, UINT nMax, UINT cbElement)
{
assert(nMax > 0 && cbElement > 0);
CPlex* p = (CPlex*) new BYTE[sizeof(CPlex) + nMax * cbElement];
// may throw exception
if (p)
{
p->pNext = pHead;
pHead = p; // change head (adds in reverse order for simplicity)
}
return p;
}
void CPlex::FreeDataChain() // free this one and links
{
CPlex* p = this;
while (p != NULL)
{
BYTE* bytes = (BYTE*) p;
CPlex* pNext = p->pNext;
delete[] bytes;
p = pNext;
}
}
/*--------- /\ stuff for collections.h /\ ---------*/
int ConvertVal(int x, int a1, int a2, int b1, int b2)
{
assert(a1 != a2 && a2 - a1);
return MulDiv(x - a1, b2 - b1, a2 - a1) + b1;
}
double dConvertVal(double x, double a1, double a2, double b1, double b2)
{
assert(a1 != a2 && a2 - a1);
return (x - a1) * (b2 - b1) / (a2 - a1) + b1;
}
SIZE GetRectSize(const RECT &rect)
{
SIZE size = {
rect.right - rect.left,
rect.bottom - rect.top};
return size;
}
SIZE GetTextSize(LPCTSTR tszText, HFONT hFont)
{
if (!tszText)
{
SIZE z = {0, 0};
return z;
}
RECT trect = {0, 0, 1, 1};
HDC hDC = CreateCompatibleDC(NULL);
if (hDC != NULL)
{
HGDIOBJ hOld = NULL;
if (hFont)
hOld = SelectObject(hDC, hFont);
DrawText(hDC, tszText, -1, &trect, DT_CALCRECT | DT_NOPREFIX);
if (hFont)
SelectObject(hDC, hOld);
DeleteDC(hDC);
}
SIZE size = {trect.right - trect.left, trect.bottom - trect.top};
return size;
}
int GetTextHeight(HFONT hFont)
{
static const TCHAR str[] = _T("Happy Test! :D");
SIZE size = GetTextSize(str, hFont);
return size.cy;
}
int vFormattedMsgBox(HINSTANCE hInstance, HWND hParent, UINT uType, UINT uTitle, UINT uMsg, va_list args)
{
int i;
const int len = 1024;
static TCHAR title[len], format[len], msg[len];
if (!LoadString(hInstance, uTitle, title, len))
_tcscpy(title, _T("(could not load title string)"));
if (!LoadString(hInstance, uMsg, format, len))
return MessageBox(hParent, _T("(could not load message/format string)"), title, uType);
#ifdef WIN95
{
char *psz = NULL;
char szDfs[1024]={0};
strcpy(szDfs,format); // make a local copy of format string
while (psz = strstr(szDfs,"%p")) // find each %p
*(psz+1) = 'x'; // replace each %p with %x
i = _vsntprintf(msg, len, szDfs, args); // use the local format string
}
#else
{
i = _vsntprintf(msg, len, format, args);
}
#endif
if (i < 0)
return MessageBox(hParent, _T("(could not format message)"), title, uType);
if (i < 1)
msg[0] = 0;
return MessageBox(hParent, msg, title, uType);
}
int FormattedMsgBox(HINSTANCE hInstance, HWND hParent, UINT uType, UINT uTitle, UINT uMsg, ...)
{
va_list args;
va_start(args, uMsg);
int i = vFormattedMsgBox(hInstance, hParent, uType, uTitle, uMsg, args);
va_end(args);
return i;
}
BOOL UserConfirm(HINSTANCE hInstance, HWND hParent, UINT uTitle, UINT uMsg, ...)
{
va_list args;
va_start(args, uMsg);
int i = vFormattedMsgBox(hInstance, hParent, MB_ICONQUESTION | MB_YESNO, uTitle, uMsg, args);
va_end(args);
return i == IDYES;
}
int FormattedErrorBox(HINSTANCE hInstance, HWND hParent, UINT uTitle, UINT uMsg, ...)
{
va_list args;
va_start(args, uMsg);
int i = vFormattedMsgBox(hInstance, hParent, MB_OK | MB_ICONSTOP, uTitle, uMsg, args);
va_end(args);
return i;
}
int FormattedLastErrorBox(HINSTANCE hInstance, HWND hParent, UINT uTitle, UINT uMsg, DWORD dwError)
{
// format an error message from GetLastError().
LPVOID lpMsgBuf = NULL;
DWORD result = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL);
if (!result || lpMsgBuf == NULL)
return FormattedErrorBox(hInstance, hParent, uTitle, uMsg,
_T("An unknown error occured (could not format the error code)."));
int i = FormattedErrorBox(hInstance, hParent, uTitle, uMsg, (LPCTSTR)lpMsgBuf);
LocalFree(lpMsgBuf);
return i;
}
LPTSTR AllocLPTSTR(LPCWSTR wstr)
{
if (wstr == NULL)
return NULL;
#ifdef UNICODE
return _tcsdup(wstr);
#else
int len = wcslen(wstr) * 2 + 1;
char *ret = (char *)malloc(len);
if (!ret)
return NULL;
WideCharToMultiByte(CP_ACP, 0, wstr, -1, ret, len, NULL, NULL);
ret[len-1] = '\0';
return ret;
#endif
}
LPTSTR AllocLPTSTR(LPCSTR str)
{
if (str == NULL)
return NULL;
#ifndef UNICODE
return _tcsdup(str);
#else
int len = strlen(str);
WCHAR *ret = (WCHAR *)malloc((len + 1) * sizeof(WCHAR));
if (!ret)
return NULL;
mbstowcs(ret, str, len);
ret[len] = L'\0';
return ret;
#endif
}
void CopyStr(LPWSTR dest, LPCWSTR src, size_t max)
{
if (dest == NULL || src == NULL)
return;
wcsncpy(dest, src, max);
}
void CopyStr(LPSTR dest, LPCSTR src, size_t max)
{
if (dest == NULL || src == NULL)
return;
strncpy(dest, src, max);
}
void CopyStr(LPWSTR dest, LPCSTR src, size_t max)
{
if (dest == NULL || src == NULL)
return;
mbstowcs(dest, src, max);
}
void CopyStr(LPSTR dest, LPCWSTR src, size_t max)
{
if (dest == NULL || src == NULL)
return;
WideCharToMultiByte(CP_ACP, 0, src, -1, dest, max, NULL, NULL);
}
LPWSTR AllocLPWSTR(LPCWSTR wstr)
{
if (wstr == NULL)
return NULL;
return _wcsdup(wstr);
}
LPWSTR AllocLPWSTR(LPCSTR str)
{
if (str == NULL)
return NULL;
size_t len = strlen(str);
size_t retsize = mbstowcs(NULL, str, len);
WCHAR *ret = (WCHAR *)malloc((retsize + 1) * sizeof(WCHAR));
if (!ret)
return NULL;
mbstowcs(ret, str, len);
ret[retsize] = L'\0';
return ret;
}
LPSTR AllocLPSTR(LPCWSTR wstr)
{
if (wstr == NULL)
return NULL;
size_t len = wcslen(wstr);
size_t retsize = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
CHAR *ret = (CHAR *)malloc((retsize + 1) * sizeof(CHAR));
if (!ret)
return NULL;
WideCharToMultiByte(CP_ACP, 0, wstr, -1, ret, retsize, NULL, NULL);
ret[retsize] = '\0';
return ret;
}
LPSTR AllocLPSTR(LPCSTR str)
{
if (str == NULL)
return NULL;
return _strdup(str);
}
LPTSTR AllocFileNameNoPath(LPTSTR path)
{
TCHAR fname[_MAX_FNAME];
TCHAR ext[_MAX_EXT];
if (path == NULL) return NULL;
_tsplitpath(path, NULL, NULL, fname, ext);
LPTSTR ret = (LPTSTR)malloc(sizeof(TCHAR) * (_tcslen(fname) + _tcslen(ext) + 1));
if (ret != NULL)
{
_tcscpy(ret, fname);
_tcscat(ret, ext);
}
return ret;
}
LPTSTR utilstr::Eject()
{
LPTSTR str = m_str;
m_str = NULL;
m_len = 0;
return str;
}
void utilstr::Empty()
{
if (m_str != NULL)
free(m_str);
m_len = 0;
}
bool utilstr::IsEmpty() const
{
return !GetLength();
}
int utilstr::GetLength() const
{
if (m_str == NULL)
return 0;
if (!m_len)
return 0;
return _tcslen(m_str);
}
void utilstr::Format(LPCTSTR format, ...)
{
static TCHAR buf[2048];
va_list args;
va_start(args, format);
#ifdef WIN95
{
char *psz = NULL;
char szDfs[1024]={0};
strcpy(szDfs,format); // make a local copy of format string
while (psz = strstr(szDfs,"%p")) // find each %p
*(psz+1) = 'x'; // replace each %p with %x
_vsntprintf(buf, sizeof(buf)/sizeof(TCHAR), szDfs, args); // use the local format string
}
#else
{
_vsntprintf(buf, sizeof(buf)/sizeof(TCHAR), format, args);
}
#endif
va_end(args);
equal(buf);
}
void utilstr::equal(LPCTSTR str)
{
Empty();
if (str == NULL)
return;
m_len = _tcslen(str);
m_str = (LPTSTR)malloc(sizeof(TCHAR) * (m_len + 1));
if (m_str != NULL)
_tcscpy(m_str, str);
else
m_len = 0;
}
void utilstr::add(LPCTSTR str)
{
if (str == NULL)
return;
if (IsEmpty())
{
equal(str);
return;
}
int len = _tcslen(str);
int newlen = m_len + len;
LPTSTR newstr = (LPTSTR)malloc(sizeof(TCHAR) * (newlen + 1));
if (newstr == NULL)
return;
_tcscpy(newstr, m_str);
_tcscat(newstr, str);
Empty();
m_str = newstr;
m_len = newlen;
}
LPTSTR AllocFlagStr(DWORD value, const AFS_FLAG flag[], int flags)
{
utilstr ret; // return string
DWORD allknownbits = 0; // check value to see if there are any bits
// set for which we don't have a define
// handle each flag
bool bflagfound = false;
for (int i = 0; i < flags; i++)
{
// set bit for this flag in allknownbits
allknownbits |= flag[i].value;
// if this bit is set in the passed value, or the value
// is zero and we're on the zero flag,
// add the define for this bit/flag to the return string
if (value ? value & flag[i].value : !flag[i].value)
{
// adding binary or operators between flags
if (bflagfound)
ret += _T(" | ");
ret += flag[i].name;
bflagfound = true;
}
}
// now see if there are any unknown bits in passed flag
DWORD unknownbits = value & ~allknownbits;
if (unknownbits)
{
// add hex number for unknown bits
utilstr unk;
unk.Format(_T("0x%08X"), unknownbits);
if (bflagfound)
ret += _T(" | ");
ret += unk;
}
// if value is zero (and no flags for zero) we should just set the string to "0"
if (!value && !bflagfound)
ret = _T("0");
// now the string should definitely not be empty, in any case
assert(!ret.IsEmpty());
// finally, add a comment that has hex number for entire value
// (for debugging)
utilstr temp;
temp.Format(_T(" /* 0x%08X */"), value);
ret += temp;
// done
return ret.Eject();
}
void PutLinePoint(HDC hDC, POINT p)
{
MoveToEx(hDC, p.x, p.y, NULL);
LineTo(hDC, p.x + 1, p.y);
}
void PolyLineArrowShadow(HDC hDC, POINT *p, int i)
{
PolyLineArrow(hDC, p, i, TRUE);
}
void PolyLineArrow(HDC hDC, POINT *rgpt, int nPoints, BOOL bDoShadow)
{
int i;
if (rgpt == NULL || nPoints < 1)
return;
if (nPoints > 1)
for (i = 0; i < nPoints - 1; i++)
{
SPOINT a = rgpt[i], b = rgpt[i + 1];
if (bDoShadow)
{
int rise = abs(b.y - a.y), run = abs(b.x - a.x);
bool vert = rise > run;
int ord = vert ? 1 : 0;
int nord = vert ? 0 : 1;
for (int o = -1; o <= 1; o += 2)
{
SPOINT c(a), d(b);
c.a[nord] += o;
d.a[nord] += o;
MoveToEx(hDC, c.x, c.y, NULL);
LineTo(hDC, d.x, d.y);
}
bool reverse = a.a[ord] > b.a[ord];
SPOINT e(reverse ? b : a), f(reverse ? a : b);
e.a[ord] -= 1;
f.a[ord] += 1;
PutLinePoint(hDC, e);
PutLinePoint(hDC, f);
}
else
{
MoveToEx(hDC, a.x, a.y, NULL);
LineTo(hDC, b.x, b.y);
}
}
POINT z = rgpt[nPoints - 1];
if (bDoShadow)
{
POINT pt[5] = {
{z.x, z.y + 2},
{z.x + 2, z.y},
{z.x, z.y - 2},
{z.x - 2, z.y}, };
pt[4] = pt[0];
Polyline(hDC, pt, 5);
}
else
{
MoveToEx(hDC, z.x - 1, z.y, NULL);
LineTo(hDC, z.x + 2, z.y);
MoveToEx(hDC, z.x, z.y - 1, NULL);
LineTo(hDC, z.x, z.y + 2);
}
}
BOOL bEq(BOOL a, BOOL b)
{
bool c = !a, d = !b;
return (c == d) ? TRUE : FALSE;
}
void DrawArrow(HDC hDC, const RECT &rect, BOOL bVert, BOOL bUpLeft)
{
SRECT srect = rect;
srect.right--;
srect.bottom--;
int ord = bVert ? 1 : 0;
int nord = bVert ? 0 : 1;
SPOINT p(!bUpLeft ? srect.lr : srect.ul), b(!bUpLeft ? srect.ul : srect.lr);
b.a[ord] += bUpLeft ? -1 : 1;
SPOINT t = p;
t.a[nord] = (p.a[nord] + b.a[nord]) / 2;
SPOINT u;
u.a[ord] = b.a[ord];
u.a[nord] = p.a[nord];
POINT poly[] = { {t.x, t.y}, {u.x, u.y}, {b.x, b.y} };
Polygon(hDC, poly, 3);
}
BOOL ScreenToClient(HWND hWnd, LPRECT rect)
{
if (rect == NULL)
return FALSE;
SRECT sr = *rect;
if (ScreenToClient(hWnd, &sr.ul.p) &&
ScreenToClient(hWnd, &sr.lr.p))
{
*rect = sr;
return TRUE;
}
return FALSE;
}
BOOL ClientToScreen(HWND hWnd, LPRECT rect)
{
if (rect == NULL)
return FALSE;
SRECT sr = *rect;
if (ClientToScreen(hWnd, &sr.ul.p) &&
ClientToScreen(hWnd, &sr.lr.p))
{
*rect = sr;
return TRUE;
}
return FALSE;
}
#define z ((L"\0")[0])
int StrLen(LPCWSTR s)
{
if (s == NULL)
return 0;
return wcslen(s);
}
int StrLen(LPCSTR s)
{
if (s == NULL)
return 0;
return strlen(s);
}

View File

@@ -0,0 +1,273 @@
//-----------------------------------------------------------------------------
// File: useful.h
//
// Desc: Contains various utility classes and functions to help the
// UI carry its operations more easily.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __USEFUL_H__
#define __USEFUL_H__
class utilstr
{
public:
utilstr() : m_str(NULL), m_len(0) {}
~utilstr() {Empty();}
operator LPCTSTR () const {return m_str;}
LPCTSTR Get() const {return m_str;}
const utilstr & operator = (const utilstr &s) {equal(s); return *this;}
const utilstr & operator = (LPCTSTR s) {equal(s); return *this;}
const utilstr & operator += (const utilstr &s) {add(s); return *this;}
const utilstr & operator += (LPCTSTR s) {add(s); return *this;}
LPTSTR Eject();
void Empty();
bool IsEmpty() const;
int GetLength() const;
void Format(LPCTSTR format, ...);
private:
LPTSTR m_str;
int m_len;
void equal(LPCTSTR str);
void add(LPCTSTR str);
};
template <class T>
struct rgref {
rgref(T *p) : pt(p) {}
T &operator [] (int i) {return pt[i];}
const T &operator [] (int i) const {return pt[i];}
private:
T *pt;
};
struct SPOINT {
SPOINT() :
#define SPOINT_INITIALIZERS \
p(u.p), \
s(u.s), \
a(((int *)(void *)u.a)), \
x(u.p.x), \
y(u.p.y), \
cx(u.s.cx), \
cy(u.s.cy)
SPOINT_INITIALIZERS
{x = y = 0;}
SPOINT(int, POINT *r) :
p(*r),
s(*((SIZE *)(void *)r)),
a(((int *)(void *)r)),
x(r->x),
y(r->y),
cx(r->x),
cy(r->y)
{}
SPOINT(const SPOINT &sp) :
SPOINT_INITIALIZERS
{p = sp.p;}
SPOINT(int b, int c) :
SPOINT_INITIALIZERS
{x = b; y = c;}
SPOINT(const POINT &point) :
SPOINT_INITIALIZERS
{p = point;}
SPOINT(const SIZE &size) :
SPOINT_INITIALIZERS
{s = size;}
#undef SPOINT_INITIALIZERS
SPOINT operator = (const SPOINT &sp) {p = sp.p; return *this;}
SPOINT operator = (const POINT &_p) {p = _p; return *this;}
SPOINT operator = (const SIZE &_s) {s = _s; return *this;}
operator POINT () const {return p;}
operator SIZE () const {return s;}
long &x, &y, &cx, &cy;
POINT &p;
SIZE &s;
rgref<int> a;
private:
union {
POINT p;
SIZE s;
int a[2];
} u;
};
struct SRECT {
SRECT() :
#define SRECT_INITIALIZERS \
a(((int *)(void *)u.a)), \
r(u.r), \
left(u.r.left), \
top(u.r.top), \
right(u.r.right), \
bottom(u.r.bottom), \
ul(0, &u.p.ul), \
lr(0, &u.p.lr)
SRECT_INITIALIZERS
{RECT z = {0,0,0,0}; u.r = z;}
SRECT(const SRECT &sr) :
SRECT_INITIALIZERS
{u.r = sr.r;}
SRECT(int c, int d, int e, int f) :
SRECT_INITIALIZERS
{RECT z = {c,d,e,f}; u.r = z;}
SRECT(const RECT &_r) :
SRECT_INITIALIZERS
{u.r = _r;}
#undef SRECT_INITIALIZERS
SRECT operator = (const SRECT &sr) {u.r = sr.r; return *this;}
SRECT operator = (const RECT &_r) {u.r = _r; return *this;}
operator RECT () const {return r;}
long &left, &top, &right, &bottom;
rgref<int> a;
RECT &r;
SPOINT ul, lr;
private:
union {
int a[4];
RECT r;
struct {
POINT ul, lr;
} p;
} u;
};
int ConvertVal(int x, int a1, int a2, int b1, int b2);
double dConvertVal(double x, double a1, double a2, double b1, double b2);
SIZE GetTextSize(LPCTSTR tszText, HFONT hFont = NULL);
int GetTextHeight(HFONT hFont);
SIZE GetRectSize(const RECT &rect);
int FormattedMsgBox(HINSTANCE, HWND, UINT, UINT, UINT, ...);
int FormattedErrorBox(HINSTANCE, HWND, UINT, UINT, ...);
int FormattedLastErrorBox(HINSTANCE, HWND, UINT, UINT, DWORD);
BOOL UserConfirm(HINSTANCE, HWND, UINT, UINT, ...);
struct AFS_FLAG {DWORD value; LPCTSTR name;};
LPTSTR AllocFlagStr(DWORD value, const AFS_FLAG flag[], DWORD flags);
LPTSTR AllocFileNameNoPath(LPTSTR path);
LPTSTR AllocLPTSTR(LPCWSTR wstr);
LPTSTR AllocLPTSTR(LPCSTR cstr);
LPWSTR AllocLPWSTR(LPCWSTR wstr);
LPWSTR AllocLPWSTR(LPCSTR str);
LPSTR AllocLPSTR(LPCWSTR wstr);
LPSTR AllocLPSTR(LPCSTR str);
void CopyStr(LPWSTR dest, LPCWSTR src, size_t max);
void CopyStr(LPSTR dest, LPCSTR src, size_t max);
void CopyStr(LPWSTR dest, LPCSTR src, size_t max);
void CopyStr(LPSTR dest, LPCWSTR src, size_t max);
void PolyLineArrowShadow(HDC hDC, POINT *p, int i);
void PolyLineArrow(HDC hDC, POINT *, int, BOOL bDoShadow = FALSE);
BOOL bEq(BOOL a, BOOL b);
void DrawArrow(HDC hDC, const RECT &rect, BOOL bVert, BOOL bUpLeft);
BOOL ScreenToClient(HWND hWnd, LPRECT rect);
BOOL ClientToScreen(HWND hWnd, LPRECT rect);
int StrLen(LPCWSTR s);
int StrLen(LPCSTR s);
template<class T>
int GetSuperStringByteSize(const T *str)
{
for (int i = 0;; i++)
if (!str[i] && !str[i + 1])
return (i + 2) * sizeof(T);
}
template<class T>
T *DupSuperString(const T *str)
{
int s = GetSuperStringByteSize(str);
T *ret = (T *)malloc(s);
if (ret != NULL)
{
CopyMemory((void *)ret, (const void *)str, (DWORD)s);
}
return ret;
}
template<class T>
int CountSubStrings(const T *str)
{
int n = 0;
while (1)
{
str += StrLen(str) + 1;
n++;
if (!*str)
return n;
}
}
template<class T>
const T *GetSubString(const T *str, int i)
{
int n = 0;
while (1)
{
if (n == i)
return str;
str += StrLen(str) + 1;
n++;
if (!*str)
return NULL;
}
}
template<class T>
class SetOnFunctionExit
{
public:
SetOnFunctionExit(T &var, T value) : m_var(var), m_value(value) {}
~SetOnFunctionExit() {m_var = m_value;}
private:
T &m_var;
T m_value;
};
#endif //__USEFUL_H__

View File

@@ -0,0 +1,343 @@
//-----------------------------------------------------------------------------
// File: usefuldi.cpp
//
// Desc: Contains various DInput-specific utility classes and functions
// to help the UI carry its operations more easily.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
// don't want useful.cpp to use precompiled header
#include "useful.cpp"
BOOL IsObjectOnExcludeList(DWORD dwOfs)
{
if (dwOfs == DIK_PREVTRACK ||
dwOfs == DIK_NEXTTRACK ||
dwOfs == DIK_MUTE ||
dwOfs == DIK_CALCULATOR ||
dwOfs == DIK_PLAYPAUSE ||
dwOfs == DIK_MEDIASTOP ||
dwOfs == DIK_VOLUMEDOWN ||
dwOfs == DIK_VOLUMEUP ||
dwOfs == DIK_WEBHOME ||
dwOfs == DIK_SLEEP ||
dwOfs == DIK_WEBSEARCH ||
dwOfs == DIK_WEBFAVORITES ||
dwOfs == DIK_WEBREFRESH ||
dwOfs == DIK_WEBSTOP ||
dwOfs == DIK_WEBFORWARD ||
dwOfs == DIK_WEBBACK ||
dwOfs == DIK_MYCOMPUTER ||
dwOfs == DIK_MAIL ||
dwOfs == DIK_MEDIASELECT ||
dwOfs == DIK_LWIN ||
dwOfs == DIK_RWIN ||
dwOfs == DIK_POWER ||
dwOfs == DIK_WAKE)
return TRUE;
return FALSE;
}
BOOL CALLBACK IncrementValPerObject(LPCDIDEVICEOBJECTINSTANCEW lpddoi, LPVOID pvRef)
{
if (pvRef != NULL)
++(*((int *)pvRef));
return DIENUM_CONTINUE;
}
BOOL CALLBACK KeyboardIncrementValPerObject(LPCDIDEVICEOBJECTINSTANCEW lpddoi, LPVOID pvRef)
{
if (pvRef != NULL && !IsObjectOnExcludeList(lpddoi->dwOfs))
++(*((int *)pvRef));
return DIENUM_CONTINUE;
}
BOOL CALLBACK FillDIDeviceObject(LPCDIDEVICEOBJECTINSTANCEW lpddoi, LPVOID pvRef)
{
if (pvRef == NULL || lpddoi == NULL)
return DIENUM_CONTINUE;
DIDEVOBJSTRUCT &os = *((DIDEVOBJSTRUCT *)pvRef);
assert(os.pdoi != NULL);
assert(os.n < os.nObjects);
if (os.pdoi != NULL && os.n < os.nObjects)
os.pdoi[os.n++] = *lpddoi;
return DIENUM_CONTINUE;
}
// This is a special EnumObjects() callback for keyboard type devices. When we enumerate, dwOfs
// member of lpddoi is meaningless. We need to take the middle 16 bits of dwType as dwOfs
// (also same as DIK_xxx).
BOOL CALLBACK FillDIKeyboardDeviceObject(LPCDIDEVICEOBJECTINSTANCEW lpddoi, LPVOID pvRef)
{
if (pvRef == NULL || lpddoi == NULL || IsObjectOnExcludeList(lpddoi->dwOfs))
return DIENUM_CONTINUE;
DIDEVOBJSTRUCT &os = *((DIDEVOBJSTRUCT *)pvRef);
assert(os.pdoi != NULL);
assert(os.n < os.nObjects);
if (os.pdoi != NULL && os.n < os.nObjects)
{
os.pdoi[os.n] = *lpddoi;
os.pdoi[os.n].dwOfs = os.pdoi[os.n].dwType >> 8;
wcscpy(os.pdoi[os.n].tszName, lpddoi->tszName);
++os.n;
}
return DIENUM_CONTINUE;
}
HRESULT FillDIDeviceObjectStruct(DIDEVOBJSTRUCT &os, LPDIRECTINPUTDEVICE8W pDID)
{
if (pDID == NULL)
return E_FAIL;
DIDEVICEINSTANCEW didi;
didi.dwSize = sizeof(didi);
pDID->GetDeviceInfo(&didi);
HRESULT hr;
if (LOBYTE(didi.dwDevType) == DI8DEVTYPE_KEYBOARD)
hr = pDID->EnumObjects(KeyboardIncrementValPerObject, &os.nObjects,
DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV);
else
hr = pDID->EnumObjects(IncrementValPerObject, &os.nObjects,
DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV);
if (FAILED(hr))
{
os.nObjects = 0;
return hr;
}
if (os.nObjects == 0)
return S_OK;
if (os.pdoi != NULL)
free(os.pdoi);
os.pdoi = (DIDEVICEOBJECTINSTANCEW *)malloc(sizeof(DIDEVICEOBJECTINSTANCEW) * os.nObjects);
if (os.pdoi == NULL)
{
os.nObjects = 0;
return E_FAIL;
}
// Check if this device is a keyboard. If so, it needs special treatment.
os.n = 0;
if ((didi.dwDevType & 0xFF) == DI8DEVTYPE_KEYBOARD)
{
hr = pDID->EnumObjects(FillDIKeyboardDeviceObject, &os,
DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV);
} else {
hr = pDID->EnumObjects(FillDIDeviceObject, &os,
DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV);
}
if (FAILED(hr))
{
os.nObjects = 0;
return hr;
}
assert(os.nObjects == os.n);
os.nObjects = os.n;
return S_OK;
}
LPTSTR AllocConfigureFlagStr(DWORD dwFlags)
{
static const AFS_FLAG flag[] = {
#define f(F) { F, _T(#F) }
f(DICD_EDIT), f(DICD_DEFAULT)
#undef f
};
static const int flags = sizeof(flag) / sizeof(AFS_FLAG);
return AllocFlagStr(dwFlags, flag, flags);
}
LPTSTR AllocActionFlagStr(DWORD dwFlags)
{
static const AFS_FLAG flag[] = {
#define f(F) { F, _T(#F) }
f(DIA_FORCEFEEDBACK),
f(DIA_APPMAPPED),
f(DIA_APPNOMAP),
f(DIA_NORANGE),
#undef f
}; static const int flags = sizeof(flag) / sizeof(AFS_FLAG);
return AllocFlagStr(dwFlags, flag, flags);
}
LPTSTR AllocActionHowFlagStr(DWORD dwFlags)
{
static const AFS_FLAG flag[] = {
#define f(F) { F, _T(#F) }
f(DIAH_UNMAPPED),
f(DIAH_USERCONFIG),
f(DIAH_APPREQUESTED),
f(DIAH_HWAPP),
f(DIAH_HWDEFAULT),
f(DIAH_DEFAULT),
f(DIAH_ERROR)
#undef f
}; static const int flags = sizeof(flag) / sizeof(AFS_FLAG);
return AllocFlagStr(dwFlags, flag, flags);
}
void CleanupActionFormatCopy(DIACTIONFORMATW &c)
{
if (c.rgoAction != NULL)
{
for (DWORD i = 0; i < c.dwNumActions; i++)
if (c.rgoAction[i].lptszActionName != NULL)
free((LPTSTR)c.rgoAction[i].lptszActionName);
free(c.rgoAction);
}
c.rgoAction = NULL;
}
HRESULT CopyActionFormat(DIACTIONFORMATW &to, const DIACTIONFORMATW &from)
{
DWORD i;
// copy all simple members
to = from;
// null copied pointers since we're going to duplicate them (makes sure cleanup works)
to.rgoAction = NULL;
// handle pointers/arrays/strings
to.rgoAction = new DIACTIONW [to.dwNumActions];
if (to.rgoAction == NULL)
goto fail;
// first null it all
memset(to.rgoAction, 0, sizeof(DIACTIONW) * to.dwNumActions);
// now copy...
for (i = 0; i < to.dwNumActions; i++)
{
// copy simple members
to.rgoAction[i] = from.rgoAction[i];
// handle pointers/arrays/strings
to.rgoAction[i].lptszActionName = _wcsdup(from.rgoAction[i].lptszActionName);
if (to.rgoAction[i].lptszActionName == NULL)
goto fail;
}
return S_OK;
fail:
CleanupActionFormatCopy(to);
return E_OUTOFMEMORY;
}
LPDIACTIONFORMATW DupActionFormat(LPCDIACTIONFORMATW lpAcFor)
{
if (!lpAcFor)
return NULL;
LPDIACTIONFORMATW pdup = new DIACTIONFORMATW;
if (!pdup)
return NULL;
if (FAILED(CopyActionFormat(*pdup, *lpAcFor)))
{
delete pdup;
return NULL;
}
return pdup;
}
void FreeActionFormatDup(LPDIACTIONFORMATW &lpAcFor)
{
if (!lpAcFor)
return;
CleanupActionFormatCopy(*lpAcFor);
delete lpAcFor;
lpAcFor = NULL;
}
void TraceActionFormat(LPTSTR header, const DIACTIONFORMATW &acf)
{
#ifdef CFGUI__TRACE_ACTION_FORMATS
tracescope(a, header);
trace(_T("\n"));
traceDWORD(acf.dwSize);
traceDWORD(acf.dwActionSize);
traceDWORD(acf.dwDataSize);
traceDWORD(acf.dwNumActions);
{tracescope(b, _T("acf.rgoAction Array\n"));
for (DWORD i = 0; i < acf.dwNumActions; i++)
{
const DIACTIONW &a = acf.rgoAction[i];
static TCHAR buf[MAX_PATH];
_stprintf(buf, _T("Action %d\n"), i);
{tracescope(c, buf);
traceHEX(a.uAppData);
traceDWORD(a.dwSemantic);
LPTSTR str = AllocActionFlagStr(a.dwFlags);
trace1(_T("a.dwFlags = %s\n"), str);
free(str);
traceWSTR(a.lptszActionName);
traceUINT(a.uResIdString);
traceDWORD(a.dwObjID);
traceGUID(a.guidInstance);
str = AllocActionHowFlagStr(a.dwHow);
trace1(_T("a.dwHow = %s\n"), str);
free(str);
}
}
}
traceGUID(acf.guidActionMap);
traceDWORD(acf.dwGenre);
traceDWORD(acf.dwBufferSize);
traceLONG(acf.lAxisMin);
traceLONG(acf.lAxisMax);
traceHEX(acf.hInstString);
traceHEX(acf.dwCRC);
traceWSTR(acf.tszActionMap);
#endif
}
BOOL IsZeroOrInvalidColorSet(const DICOLORSET &cs)
{
if (cs.dwSize < sizeof(DICOLORSET))
return TRUE;
const int colors = 8;
D3DCOLOR color[colors] = {
cs.cTextFore,
cs.cTextHighlight,
cs.cCalloutLine,
cs.cCalloutHighlight,
cs.cBorder,
cs.cControlFill,
cs.cHighlightFill,
cs.cAreaFill
};
for (int i = 0; i < colors; i++)
if (color[i])
return FALSE;
return TRUE;
}
// D3DCOLOR2COLORREF swaps the blue and red components since GDI and D3D store RGB in the opposite order.
// It also removes the alpha component as the GDI doesn't use that, and including it causes incorrect color.
COLORREF D3DCOLOR2COLORREF(D3DCOLOR c)
{
LPBYTE pC = (LPBYTE)&c;
return (COLORREF)((DWORD(*pC) << 16) + (DWORD(*(pC+1)) << 8) + DWORD(*(pC+2)));
}

View File

@@ -0,0 +1,39 @@
//-----------------------------------------------------------------------------
// File: usefuldi.h
//
// Desc: Contains various DInput-specific utility classes and functions
// to help the UI carry its operations more easily.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef __USEFULDI_H__
#define __USEFULDI_H__
struct DIDEVOBJSTRUCT {
DIDEVOBJSTRUCT() : nObjects(0), pdoi(NULL) {}
~DIDEVOBJSTRUCT() {if (pdoi != NULL) free(pdoi);}
DWORD GetTypeFromObjID(DWORD);
int nObjects;
DIDEVICEOBJECTINSTANCEW *pdoi;
int n;
};
HRESULT FillDIDeviceObjectStruct(DIDEVOBJSTRUCT &os, LPDIRECTINPUTDEVICE8W pDID);
LPTSTR AllocConfigureFlagStr(DWORD dwFlags);
LPTSTR AllocActionFlagStr(DWORD dwFlags);
LPTSTR AllocActionHowFlagStr(DWORD dwFlags);
void CleanupActionFormatCopy(DIACTIONFORMATW &c);
HRESULT CopyActionFormat(DIACTIONFORMATW &to, const DIACTIONFORMATW &from);
LPDIACTIONFORMATW DupActionFormat(LPCDIACTIONFORMATW lpAcFor);
void FreeActionFormatDup(LPDIACTIONFORMATW &lpAcFor);
void TraceActionFormat(LPTSTR header, const DIACTIONFORMATW &acf);
BOOL IsZeroOrInvalidColorSet(const DICOLORSET &);
COLORREF D3DCOLOR2COLORREF(D3DCOLOR c);
#endif //__USEFULDI_H__

View File

@@ -0,0 +1,113 @@
//-----------------------------------------------------------------------------
// File: viewselwnd.cpp
//
// Desc: Implements CViewSelWnd class (derived from CFlexWnd). CViewSelWnd
// is used by the page object when a device has more than one view.
// CViewSelWnd displays one thumbnail for each view. The user can then
// select which view he/she wants to see with the mouse.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
CViewSelWnd::CViewSelWnd() :
m_pUI(NULL), m_nOver(-1)
{
}
CViewSelWnd::~CViewSelWnd()
{
}
BOOL CViewSelWnd::Go(HWND hParent, int left, int bottom, CDeviceUI *pUI)
{
if (pUI == NULL)
{
assert(0);
return FALSE;
}
m_pUI = pUI;
int w = 2 + g_sizeThumb.cx * pUI->GetNumViews();
int h = 2 + g_sizeThumb.cy;
RECT rect = {left, bottom - h, left + w, bottom};
if (!Create(hParent, rect, FALSE))
return FALSE;
assert(m_hWnd);
if (!m_hWnd)
return FALSE;
SetWindowPos(m_hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
SetCapture();
return TRUE;
}
void CViewSelWnd::OnPaint(HDC hDC)
{
for (int i = 0; i < m_pUI->GetNumViews(); i++)
{
CBitmap *pbm = m_pUI->GetViewThumbnail(i, i == m_nOver);
if (pbm != NULL)
pbm->Draw(hDC, i * g_sizeThumb.cx + 1, 1);
}
CPaintHelper ph(m_pUI->m_uig, hDC);
ph.SetPen(UIP_VIEWSELGRID);
RECT rect;
GetClientRect(&rect);
ph.Rectangle(rect, UIR_OUTLINE);
}
void CViewSelWnd::OnMouseOver(POINT point, WPARAM fwKeys)
{
RECT rect;
GetClientRect(&rect);
InflateRect(&rect, -1, -1);
if (PtInRect(&rect, point))
m_nOver = point.x / g_sizeThumb.cx;
else
m_nOver = -1;
Invalidate();
}
void CViewSelWnd::OnClick(POINT point, WPARAM fwKeys, BOOL bLeft)
{
if (!bLeft)
return;
OnMouseOver(point, fwKeys);
if (m_nOver != -1)
{
DEVICEUINOTIFY uin;
uin.msg = DEVUINM_SELVIEW;
uin.from = DEVUINFROM_SELWND;
uin.selview.nView = m_nOver;
m_pUI->Notify(uin);
}
ReleaseCapture();
Destroy();
}
LRESULT CViewSelWnd::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
LRESULT lr = CFlexWnd::WndProc(hWnd, msg, wParam, lParam);
switch (msg)
{
case WM_CAPTURECHANGED:
Destroy();
break;
}
return lr;
}

View File

@@ -0,0 +1,46 @@
//-----------------------------------------------------------------------------
// File: viewselwnd.h
//
// Desc: Implements CViewSelWnd class (derived from CFlexWnd). CViewSelWnd
// is used by the page object when a device has more than one view.
// CViewSelWnd displays one thumbnail for each view. The user can then
// select which view he/she wants to see with the mouse.
//
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifdef FORWARD_DECLS
class CViewSelWnd;
#else // FORWARD_DECLS
#ifndef __VIEWSELWND_H__
#define __VIEWSELWND_H__
class CViewSelWnd : public CFlexWnd
{
public:
CViewSelWnd();
~CViewSelWnd();
BOOL Go(HWND hParent, int left, int bottom, CDeviceUI *pUI);
protected:
virtual void OnPaint(HDC hDC);
virtual void OnMouseOver(POINT point, WPARAM fwKeys);
virtual void OnClick(POINT point, WPARAM fwKeys, BOOL bLeft);
virtual LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
CDeviceUI *m_pUI;
int m_nOver;
};
#endif //__VIEWSELWND_H__
#endif // FORWARD_DECLS

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,555 @@
//-----------------------------------------------------------------------------
// File: FFConst.cpp
//
// Desc: Demonstrates an application which sets a force feedback constant force
// determined by the user.
//
// Copyright (c) 1998-2001 Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#define STRICT
#include <tchar.h>
#include <windows.h>
#include <windowsx.h>
#include <basetsd.h>
#include <mmsystem.h>
#include <dinput.h>
#include <math.h>
#include "resource.h"
//-----------------------------------------------------------------------------
// Function prototypes
//-----------------------------------------------------------------------------
INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );
BOOL CALLBACK EnumFFDevicesCallback( const DIDEVICEINSTANCE* pInst, VOID* pContext );
BOOL CALLBACK EnumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext );
HRESULT InitDirectInput( HWND hDlg );
VOID FreeDirectInput();
VOID OnPaint( HWND hDlg );
HRESULT OnMouseMove( HWND hDlg, INT x, INT y, UINT keyFlags );
VOID OnLeftButtonDown( HWND hDlg, INT x, INT y, UINT keyFlags );
VOID OnLeftButtonUp( HWND hDlg, INT x, INT y, UINT keyFlags );
INT CoordToForce( INT x );
HRESULT SetDeviceForcesXY();
//-----------------------------------------------------------------------------
// Defines, constants, and global variables
//-----------------------------------------------------------------------------
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
#define FEEDBACK_WINDOW_X 20
#define FEEDBACK_WINDOW_Y 60
#define FEEDBACK_WINDOW_WIDTH 200
LPDIRECTINPUT8 g_pDI = NULL;
LPDIRECTINPUTDEVICE8 g_pDevice = NULL;
LPDIRECTINPUTEFFECT g_pEffect = NULL;
BOOL g_bActive = TRUE;
DWORD g_dwNumForceFeedbackAxis = 0;
INT g_nXForce;
INT g_nYForce;
DWORD g_dwLastEffectSet; // Time of the previous force feedback effect set
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Entry point for the application. Since we use a simple dialog for
// user interaction we don't need to pump messages.
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
// Display the main dialog box.
DialogBox( hInst, MAKEINTRESOURCE(IDD_FORCE_FEEDBACK), NULL, MainDlgProc );
return TRUE;
}
//-----------------------------------------------------------------------------
// Name: MainDlgProc
// Desc: Handles dialog messages
//-----------------------------------------------------------------------------
INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_INITDIALOG:
if( FAILED( InitDirectInput( hDlg ) ) )
{
MessageBox( NULL, _T("Error Initializing DirectInput ")
_T("The sample will now exit."),
_T("FFConst"), MB_ICONERROR | MB_OK );
EndDialog( hDlg, 0 );
}
// Init the time of the last force feedback effect
g_dwLastEffectSet = timeGetTime();
break;
case WM_MOUSEMOVE:
if( FAILED( OnMouseMove( hDlg, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), (UINT)wParam ) ) )
{
MessageBox( NULL, _T("Error setting effect parameters. ")
_T("The sample will now exit."),
_T("FFConst"), MB_ICONERROR | MB_OK );
EndDialog( hDlg, 0 );
}
break;
case WM_LBUTTONDOWN:
OnLeftButtonDown( hDlg, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), (UINT)wParam );
break;
case WM_LBUTTONUP:
OnLeftButtonUp( hDlg, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), (UINT)wParam );
break;
case WM_PAINT:
OnPaint( hDlg );
break;
case WM_ACTIVATE:
if( WA_INACTIVE != wParam && g_pDevice )
{
// Make sure the device is acquired, if we are gaining focus.
g_pDevice->Acquire();
if( g_pEffect )
g_pEffect->Start( 1, 0 ); // Start the effect
}
break;
case WM_COMMAND:
switch( LOWORD(wParam) )
{
case IDCANCEL:
EndDialog( hDlg, 0 );
break;
default:
return FALSE; // Message not handled
}
break;
case WM_DESTROY:
// Cleanup everything
KillTimer( hDlg, 0 );
FreeDirectInput();
break;
default:
return FALSE; // Message not handled
}
return TRUE; // Message handled
}
//-----------------------------------------------------------------------------
// Name: InitDirectInput()
// Desc: Initialize the DirectInput variables.
//-----------------------------------------------------------------------------
HRESULT InitDirectInput( HWND hDlg )
{
DIPROPDWORD dipdw;
HRESULT hr;
// Register with the DirectInput subsystem and get a pointer
// to a IDirectInput interface we can use.
if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION,
IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) )
{
return hr;
}
// Look for a force feedback device we can use
if( FAILED( hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL,
EnumFFDevicesCallback, NULL,
DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK ) ) )
{
return hr;
}
if( NULL == g_pDevice )
{
MessageBox( NULL, _T("Force feedback device not found. ")
_T("The sample will now exit."),
_T("FFConst"), MB_ICONERROR | MB_OK );
EndDialog( hDlg, 0 );
return S_OK;
}
// Set the data format to "simple joystick" - a predefined data format. A
// data format specifies which controls on a device we are interested in,
// and how they should be reported.
//
// This tells DirectInput that we will be passing a DIJOYSTATE structure to
// IDirectInputDevice8::GetDeviceState(). Even though we won't actually do
// it in this sample. But setting the data format is important so that the
// DIJOFS_* values work properly.
if( FAILED( hr = g_pDevice->SetDataFormat( &c_dfDIJoystick ) ) )
return hr;
// Set the cooperative level to let DInput know how this device should
// interact with the system and with other DInput applications.
// Exclusive access is required in order to perform force feedback.
if( FAILED( hr = g_pDevice->SetCooperativeLevel( hDlg,
DISCL_EXCLUSIVE |
DISCL_FOREGROUND ) ) )
{
return hr;
}
// Since we will be playing force feedback effects, we should disable the
// auto-centering spring.
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = FALSE;
if( FAILED( hr = g_pDevice->SetProperty( DIPROP_AUTOCENTER, &dipdw.diph ) ) )
return hr;
// Enumerate and count the axes of the joystick
if ( FAILED( hr = g_pDevice->EnumObjects( EnumAxesCallback,
(VOID*)&g_dwNumForceFeedbackAxis, DIDFT_AXIS ) ) )
return hr;
// This simple sample only supports one or two axis joysticks
if( g_dwNumForceFeedbackAxis > 2 )
g_dwNumForceFeedbackAxis = 2;
// This application needs only one effect: Applying raw forces.
DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y };
LONG rglDirection[2] = { 0, 0 };
DICONSTANTFORCE cf = { 0 };
DIEFFECT eff;
ZeroMemory( &eff, sizeof(eff) );
eff.dwSize = sizeof(DIEFFECT);
eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
eff.dwDuration = INFINITE;
eff.dwSamplePeriod = 0;
eff.dwGain = DI_FFNOMINALMAX;
eff.dwTriggerButton = DIEB_NOTRIGGER;
eff.dwTriggerRepeatInterval = 0;
eff.cAxes = g_dwNumForceFeedbackAxis;
eff.rgdwAxes = rgdwAxes;
eff.rglDirection = rglDirection;
eff.lpEnvelope = 0;
eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
eff.lpvTypeSpecificParams = &cf;
eff.dwStartDelay = 0;
// Create the prepared effect
if( FAILED( hr = g_pDevice->CreateEffect( GUID_ConstantForce,
&eff, &g_pEffect, NULL ) ) )
{
return hr;
}
if( NULL == g_pEffect )
return E_FAIL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: EnumAxesCallback()
// Desc: Callback function for enumerating the axes on a joystick and counting
// each force feedback enabled axis
//-----------------------------------------------------------------------------
BOOL CALLBACK EnumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
VOID* pContext )
{
DWORD* pdwNumForceFeedbackAxis = (DWORD*) pContext;
if( (pdidoi->dwFlags & DIDOI_FFACTUATOR) != 0 )
(*pdwNumForceFeedbackAxis)++;
return DIENUM_CONTINUE;
}
//-----------------------------------------------------------------------------
// Name: EnumFFDevicesCallback()
// Desc: Called once for each enumerated force feedback device. If we find
// one, create a device interface on it so we can play with it.
//-----------------------------------------------------------------------------
BOOL CALLBACK EnumFFDevicesCallback( const DIDEVICEINSTANCE* pInst,
VOID* pContext )
{
LPDIRECTINPUTDEVICE8 pDevice;
HRESULT hr;
// Obtain an interface to the enumerated force feedback device.
hr = g_pDI->CreateDevice( pInst->guidInstance, &pDevice, NULL );
// If it failed, then we can't use this device for some
// bizarre reason. (Maybe the user unplugged it while we
// were in the middle of enumerating it.) So continue enumerating
if( FAILED(hr) )
return DIENUM_CONTINUE;
// We successfully created an IDirectInputDevice8. So stop looking
// for another one.
g_pDevice = pDevice;
return DIENUM_STOP;
}
//-----------------------------------------------------------------------------
// Name: FreeDirectInput()
// Desc: Initialize the DirectInput variables.
//-----------------------------------------------------------------------------
VOID FreeDirectInput()
{
// Unacquire the device one last time just in case
// the app tried to exit while the device is still acquired.
if( g_pDevice )
g_pDevice->Unacquire();
// Release any DirectInput objects.
SAFE_RELEASE( g_pEffect );
SAFE_RELEASE( g_pDevice );
SAFE_RELEASE( g_pDI );
}
//-----------------------------------------------------------------------------
// Name: OnPaint()
// Desc: Handles the WM_PAINT window message
//-----------------------------------------------------------------------------
VOID OnPaint( HWND hDlg )
{
PAINTSTRUCT ps;
HDC hDC;
HPEN hpenOld;
HPEN hpenBlack;
HBRUSH hbrOld;
HBRUSH hbrBlack;
INT x;
INT y;
hDC = BeginPaint( hDlg, &ps );
if( NULL == hDC )
return;
// Everything is scaled to the size of the window.
hpenBlack = GetStockPen( BLACK_PEN );
hpenOld = SelectPen( hDC, hpenBlack );
// Draw force feedback bounding rect
MoveToEx( hDC, FEEDBACK_WINDOW_X, FEEDBACK_WINDOW_Y, NULL );
LineTo( hDC, FEEDBACK_WINDOW_X,
FEEDBACK_WINDOW_Y + FEEDBACK_WINDOW_WIDTH );
LineTo( hDC, FEEDBACK_WINDOW_X + FEEDBACK_WINDOW_WIDTH,
FEEDBACK_WINDOW_Y + FEEDBACK_WINDOW_WIDTH );
LineTo( hDC, FEEDBACK_WINDOW_X + FEEDBACK_WINDOW_WIDTH,
FEEDBACK_WINDOW_Y );
LineTo( hDC, FEEDBACK_WINDOW_X,
FEEDBACK_WINDOW_Y );
// Calculate center of feedback window for center marker
x = FEEDBACK_WINDOW_X + FEEDBACK_WINDOW_WIDTH / 2;
y = FEEDBACK_WINDOW_Y + FEEDBACK_WINDOW_WIDTH / 2;
// Draw center marker
MoveToEx( hDC, x, y - 10, NULL );
LineTo( hDC, x, y + 10 + 1 );
MoveToEx( hDC, x - 10, y, NULL );
LineTo( hDC, x + 10 + 1, y );
hbrBlack = GetStockBrush( BLACK_BRUSH );
hbrOld = SelectBrush( hDC, hbrBlack );
x = MulDiv( FEEDBACK_WINDOW_WIDTH,
g_nXForce + DI_FFNOMINALMAX,
2 * DI_FFNOMINALMAX );
y = MulDiv( FEEDBACK_WINDOW_WIDTH,
g_nYForce + DI_FFNOMINALMAX,
2 * DI_FFNOMINALMAX );
x += FEEDBACK_WINDOW_X;
y += FEEDBACK_WINDOW_Y;
Ellipse( hDC, x-5, y-5, x+6, y+6 );
SelectBrush( hDC, hbrOld );
SelectPen( hDC, hpenOld );
EndPaint( hDlg, &ps );
}
//-----------------------------------------------------------------------------
// Name: OnMouseMove()
// Desc: If the mouse button is down, then change the direction of
// the force to match the new location.
//-----------------------------------------------------------------------------
HRESULT OnMouseMove( HWND hDlg, INT x, INT y, UINT keyFlags )
{
HRESULT hr;
DWORD dwCurrentTime;
if( NULL == g_pEffect )
return S_OK;
if( keyFlags & MK_LBUTTON )
{
dwCurrentTime = timeGetTime();
if( dwCurrentTime - g_dwLastEffectSet < 100 )
{
// Don't allow setting effect more often than
// 100ms since every time an effect is set, the
// device will jerk.
//
// Note: This is not neccessary, and is specific to this sample
return S_OK;
}
g_dwLastEffectSet = dwCurrentTime;
x -= FEEDBACK_WINDOW_X;
y -= FEEDBACK_WINDOW_Y;
g_nXForce = CoordToForce( x );
g_nYForce = CoordToForce( y );
InvalidateRect( hDlg, 0, TRUE );
UpdateWindow( hDlg );
if( FAILED( hr = SetDeviceForcesXY() ) )
return hr;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: OnLeftButtonDown()
// Desc: Capture the mouse so we can follow it, and start updating the
// force information.
//-----------------------------------------------------------------------------
VOID OnLeftButtonDown( HWND hDlg, INT x, INT y, UINT keyFlags )
{
SetCapture( hDlg );
OnMouseMove( hDlg, x, y, MK_LBUTTON );
}
//-----------------------------------------------------------------------------
// Name: OnLeftButtonUp()
// Desc: Stop capturing the mouse when the button goes up.
//-----------------------------------------------------------------------------
VOID OnLeftButtonUp( HWND hDlg, INT x, INT y, UINT keyFlags )
{
ReleaseCapture();
}
//-----------------------------------------------------------------------------
// Name: CoordToForce()
// Desc: Convert a coordinate 0 <= nCoord <= FEEDBACK_WINDOW_WIDTH
// to a force value in the range -DI_FFNOMINALMAX to +DI_FFNOMINALMAX.
//-----------------------------------------------------------------------------
INT CoordToForce( INT nCoord )
{
INT nForce = MulDiv( nCoord, 2 * DI_FFNOMINALMAX, FEEDBACK_WINDOW_WIDTH )
- DI_FFNOMINALMAX;
// Keep force within bounds
if( nForce < -DI_FFNOMINALMAX )
nForce = -DI_FFNOMINALMAX;
if( nForce > +DI_FFNOMINALMAX )
nForce = +DI_FFNOMINALMAX;
return nForce;
}
//-----------------------------------------------------------------------------
// Name: SetDeviceForcesXY()
// Desc: Apply the X and Y forces to the effect we prepared.
//-----------------------------------------------------------------------------
HRESULT SetDeviceForcesXY()
{
// Modifying an effect is basically the same as creating a new one, except
// you need only specify the parameters you are modifying
LONG rglDirection[2] = { 0, 0 };
DICONSTANTFORCE cf;
if( g_dwNumForceFeedbackAxis == 1 )
{
// If only one force feedback axis, then apply only one direction and
// keep the direction at zero
cf.lMagnitude = g_nXForce;
rglDirection[0] = 0;
}
else
{
// If two force feedback axis, then apply magnitude from both directions
rglDirection[0] = g_nXForce;
rglDirection[1] = g_nYForce;
cf.lMagnitude = (DWORD)sqrt( (double)g_nXForce * (double)g_nXForce +
(double)g_nYForce * (double)g_nYForce );
}
DIEFFECT eff;
ZeroMemory( &eff, sizeof(eff) );
eff.dwSize = sizeof(DIEFFECT);
eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
eff.cAxes = g_dwNumForceFeedbackAxis;
eff.rglDirection = rglDirection;
eff.lpEnvelope = 0;
eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
eff.lpvTypeSpecificParams = &cf;
eff.dwStartDelay = 0;
// Now set the new parameters and start the effect immediately.
return g_pEffect->SetParameters( &eff, DIEP_DIRECTION |
DIEP_TYPESPECIFICPARAMS |
DIEP_START );
}

Some files were not shown because too many files have changed in this diff Show More