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>
@@ -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
|
||||
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
After Width: | Height: | Size: 106 B |
@@ -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__
|
||||
BIN
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/bitmap1.bmp
Normal file
|
After Width: | Height: | Size: 146 B |
|
After Width: | Height: | Size: 106 B |
726
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/cbitmap.cpp
Normal 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;
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
232
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/cdeviceui.h
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
1852
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/cdiacpage.cpp
Normal file
192
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/cdiacpage.h
Normal 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
|
||||
@@ -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
|
||||
@@ -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__
|
||||
260
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/cfrmwrk.cpp
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
After Width: | Height: | Size: 90 B |
1240
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/collections.h
Normal file
102
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/common.hpp
Normal 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__
|
||||
2097
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/configwnd.cpp
Normal file
248
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/configwnd.h
Normal 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__
|
||||
@@ -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};
|
||||
@@ -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__
|
||||
@@ -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);}
|
||||
@@ -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__
|
||||
139
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/dconfig.rc
Normal 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
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
@@ -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__
|
||||
@@ -0,0 +1,7 @@
|
||||
LIBRARY diconfig.dll
|
||||
|
||||
EXPORTS
|
||||
DllGetClassObject PRIVATE
|
||||
DllCanUnloadNow PRIVATE
|
||||
DllRegisterServer PRIVATE
|
||||
DllUnregisterServer PRIVATE
|
||||
101
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/dicfgres.h
Normal 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
|
||||
@@ -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
|
||||
@@ -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>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
1323
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/flextree.cpp
Normal file
297
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/flextree.h
Normal 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__
|
||||
621
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/flexwnd.cpp
Normal 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);
|
||||
}
|
||||
132
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/flexwnd.h
Normal 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__
|
||||
15
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/guids.c
Normal 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"
|
||||
|
After Width: | Height: | Size: 102 B |
BIN
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/ib.bmp
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/ib2.bmp
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
@@ -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()
|
||||
{
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
124
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/main.cpp
Normal 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;
|
||||
}
|
||||
18
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/main.h
Normal 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__
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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__
|
||||
511
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/privcom.cpp
Normal 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, ®, (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, ®, (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);
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
221
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/uiglobals.h
Normal 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__
|
||||
626
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/useful.cpp
Normal 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);
|
||||
}
|
||||
|
||||
273
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/useful.h
Normal 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, ⊥
|
||||
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__
|
||||
@@ -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)));
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
BIN
Library/dxx8/samples/Multimedia/DirectInput/FFConst/directx.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
555
Library/dxx8/samples/Multimedia/DirectInput/FFConst/ffconst.cpp
Normal 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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||