windows-nt/Source/XPSP1/NT/shell/osshell/control/joy/joymisc.c
2020-09-26 16:20:57 +08:00

437 lines
10 KiB
C

//****************************************************************************
//
// File: joymisc.c
// Content: Misc routines used by calibration and testing dialogs
// History:
// Date By Reason
// ==== == ======
// 11-dec-94 craige split out of joycpl.c
// 15-dec-94 craige allow N joysticks
// 18-dec-94 craige process U&V
// 04-mar-95 craige bug 13147: crosshair should erase background color
//
// Copyright (c) Microsoft Corporation 1994-1995
//
//****************************************************************************
#include "joycpl.h"
/*
* ADJ_VAL is used to convert a joystick position into a value in
* a new range
*/
#define ADJ_VAL( a, pos, range ) (((pos-(pgv->joyRange.jpMin.dw##a))*range)/ \
(pgv->joyRange.jpMax.dw##a-pgv->joyRange.jpMin.dw##a+1))
/*
* setOEMWindowText - set window text with an OEM string
*/
static void setOEMWindowText( HWND hwnd, int id, LPSTR str )
{
HWND hwndctl;
if( str[0] != 0 ) {
hwndctl = GetDlgItem( hwnd, id );
if( hwndctl != NULL ) {
SetWindowText( hwndctl, str );
}
}
} /* setOEMWindowText */
/*
* SetOEMText - set OEM defined text in the dialogs
*/
void SetOEMText( LPGLOBALVARS pgv, HWND hwnd, BOOL istest )
{
DWORD type;
char str[MAX_STR];
char res[MAX_STR];
HINSTANCE hinst;
int id;
LPSTR pwincap;
LPJOYDATA pjd;
pjd = pgv->pjd;
/*
* get the default window caption. this will be replaced by
* an OEM string if it is avaliable.
*/
hinst = GetWindowInstance( hwnd );
if( istest ) {
id = IDS_JOYTESTCAPN;
} else {
id = IDS_JOYCALCAPN;
}
if( !LoadString( hinst, id, str, sizeof( str ) ) ) {
res[0] = 0;
} else {
wsprintf( res, str, pgv->iJoyId+1 );
}
pwincap = res;
/*
* if this is an OEM joystick, use any strings that they may have defined
*/
if( pgv->joyHWCurr.dwUsageSettings & JOY_US_ISOEM ) {
type = pgv->joyHWCurr.dwType - JOY_HW_LASTENTRY;
/*
* set up labels under each of the controls
*/
setOEMWindowText( hwnd, IDC_JOYLIST1_LABEL, pjd->oemList[type].xy_label );
setOEMWindowText( hwnd, IDC_JOYLIST2_LABEL, pjd->oemList[type].z_label );
setOEMWindowText( hwnd, IDC_JOYLIST3_LABEL, pjd->oemList[type].r_label );
setOEMWindowText( hwnd, IDC_JOYLIST4_LABEL, pjd->oemList[type].u_label );
setOEMWindowText( hwnd, IDC_JOYLIST5_LABEL, pjd->oemList[type].v_label );
setOEMWindowText( hwnd, IDC_JOYPOV_LABEL, pjd->oemList[type].pov_label );
if( istest ) {
/*
* set the various caption and description fields in the test dlg
*/
setOEMWindowText( hwnd, IDC_TEXT_1, pjd->oemList[type].testmove_desc );
setOEMWindowText( hwnd, IDC_TEXT_2, pjd->oemList[type].testbutton_desc );
setOEMWindowText( hwnd, IDC_GROUPBOX, pjd->oemList[type].testmove_cap );
setOEMWindowText( hwnd, IDC_GROUPBOX_2, pjd->oemList[type].testbutton_cap );
if( pjd->oemList[type].testwin_cap[0] != 0 ) {
pwincap = pjd->oemList[type].testwin_cap;
}
} else {
/*
* set the various caption and description fields in the
* calibration dialog
*/
setOEMWindowText( hwnd, IDC_GROUPBOX, pjd->oemList[type].cal_cap );
if( pjd->oemList[type].calwin_cap[0] != 0 ) {
pwincap = pjd->oemList[type].calwin_cap;
}
}
}
/*
* set the window caption
*/
if( pwincap[0] != 0 ) {
SetWindowText( hwnd, pwincap );
}
} /* SetOEMText */
/*
* ShowControls - show Z and R controls, based on configuration info
*/
void ShowControls( LPJOYREGHWCONFIG pcfg, HWND hwnd )
{
HWND hwndctl;
/*
* hide Z indicatior if there is no Z axis
*/
if( !(pcfg->hws.dwFlags & JOY_HWS_HASZ) ) {
ShowWindow( GetDlgItem( hwnd, IDC_JOYLIST2 ), SW_HIDE );
ShowWindow( GetDlgItem( hwnd, IDC_JOYLIST2_LABEL ), SW_HIDE );
}
/*
* hide R indicatior if there is no R axis or rudder
*/
if( !(pcfg->hws.dwFlags & JOY_HWS_HASR) && !(pcfg->dwUsageSettings & JOY_US_HASRUDDER) ) {
ShowWindow( GetDlgItem( hwnd, IDC_JOYLIST3 ), SW_HIDE );
ShowWindow( GetDlgItem( hwnd, IDC_JOYLIST3_LABEL ), SW_HIDE );
}
/*
* hide POV indicatior if there is no POV
*/
if( !(pcfg->hws.dwFlags & JOY_HWS_HASPOV) ) {
ShowWindow( GetDlgItem( hwnd, IDC_JOYPOV ), SW_HIDE );
ShowWindow( GetDlgItem( hwnd, IDC_JOYPOV_LABEL ), SW_HIDE );
}
/*
* hide U indicatior if there is no U axis
*/
if( !(pcfg->hws.dwFlags & JOY_HWS_HASU) ) {
hwndctl = GetDlgItem( hwnd, IDC_JOYLIST4 );
if( hwndctl != NULL ) {
ShowWindow( hwndctl, SW_HIDE );
ShowWindow( GetDlgItem( hwnd, IDC_JOYLIST4_LABEL ), SW_HIDE );
}
}
/*
* hide V indicatior if there is no V axis
*/
if( !(pcfg->hws.dwFlags & JOY_HWS_HASV) ) {
hwndctl = GetDlgItem( hwnd, IDC_JOYLIST5 );
if( hwndctl != NULL ) {
ShowWindow( hwndctl, SW_HIDE );
ShowWindow( GetDlgItem( hwnd, IDC_JOYLIST5_LABEL ), SW_HIDE );
}
}
} /* ShowControls */
/*
* JoyError - error reading the joystick
*/
BOOL JoyError( HWND hwnd )
{
char str1[MAX_STR];
char str2[MAX_STR];
int rc;
HINSTANCE hinst;
hinst = GetWindowInstance( hwnd );
rc = IDCANCEL;
if( LoadString( hinst, IDS_JOYREADERROR, str1, sizeof( str1 ) ) ) {
if( LoadString( hinst, IDS_JOYUNPLUGGED, str2, sizeof( str2 ) ) ) {
rc = MessageBox( hwnd, str2, str1,
MB_RETRYCANCEL | MB_ICONERROR | MB_TASKMODAL );
}
}
if( rc == IDCANCEL ) {
/*
* terminate the dialog if we give up
*/
PostMessage( hwnd, WM_COMMAND, IDCANCEL, 0 );
return FALSE;
}
return TRUE;
} /* JoyError */
/*
* ChangeIcon - change the icon of a static control
*/
void ChangeIcon( HWND hwnd, int idi, int idc )
{
HINSTANCE hinst;
HICON hicon;
HICON holdicon;
hinst = GetWindowInstance( hwnd );
hicon = LoadIcon( hinst, MAKEINTRESOURCE(idi) );
if( hicon != NULL ) {
holdicon = Static_SetIcon( GetDlgItem(hwnd,idc), hicon );
if( holdicon != NULL ) {
DestroyIcon( holdicon );
}
}
} /* ChangeIcon */
/*
* CauseRedraw - cause test or calibrate dialogs to redraw their controls
*/
void CauseRedraw( LPJOYINFOEX pji, BOOL do_buttons )
{
pji->dwXpos = (DWORD) -1;
pji->dwYpos = (DWORD) -1;
pji->dwZpos = (DWORD) -1;
pji->dwRpos = (DWORD) -1;
pji->dwPOV = JOY_POVCENTERED;
if( do_buttons ) {
pji->dwButtons = ALL_BUTTONS;
}
} /* CauseRedraw */
/*
* fillBar - fill the bar for indicating Z or R info
*/
static void fillBar( LPGLOBALVARS pgv, HWND hwnd, DWORD pos, int id )
{
HWND hwlb;
RECT r;
HDC hdc;
int height;
LPJOYDATA pjd;
pjd = pgv->pjd;
/*
* scale the height to be inside the bar window
*/
hwlb = GetDlgItem( hwnd, id );
if( hwlb == NULL ) {
return;
}
hdc = GetDC( hwlb );
if( hdc == NULL ) {
return;
}
GetClientRect( hwlb, &r );
switch( id ) {
case IDC_JOYLIST2:
height = ADJ_VAL( Z, pos, r.bottom );
break;
case IDC_JOYLIST3:
height = ADJ_VAL( R, pos, r.bottom );
break;
case IDC_JOYLIST4:
height = ADJ_VAL( U, pos, r.bottom );
break;
case IDC_JOYLIST5:
height = ADJ_VAL( V, pos, r.bottom );
break;
}
/*
* fill in the inactive area
*/
r.top = height;
FillRect( hdc, &r, pjd->hbUp );
/*
* fill in the active area
*/
r.top = 0;
r.bottom = height;
FillRect( hdc, &r, pjd->hbDown );
ReleaseDC( hwlb, hdc );
} /* fillBar */
#define DELTA 5
/*
* drawCross - draw a cross in the position box
*/
static void drawCross( HWND hwnd, int x, int y, int obj )
{
HDC hdc;
HPEN hpen;
HPEN holdpen;
hdc = GetDC( hwnd );
if( hdc == NULL ) {
return;
}
if( obj == -1 ) {
COLORREF cr;
cr = GetSysColor( COLOR_WINDOW );
hpen = CreatePen( PS_SOLID, 0, cr );
} else {
hpen = GetStockObject( obj );
}
if( hpen == NULL ) {
ReleaseDC( hwnd, hdc );
return;
}
holdpen = SelectObject( hdc, hpen );
MoveToEx( hdc, x-(DELTA-1), y, NULL );
LineTo( hdc, x+DELTA, y );
MoveToEx( hdc, x, y-(DELTA-1), NULL );
LineTo( hdc, x, y+DELTA );
SelectObject( hdc, holdpen );
if( obj == -1 ) {
DeleteObject( hpen );
}
ReleaseDC( hwnd, hdc );
} /* drawCross */
#define FILLBAR( a, id ) \
/* \
* make sure we aren't out of alleged range \
*/ \
if( pji->dw##a##pos > pgv->joyRange.jpMax.dw##a ) { \
pji->dw##a##pos = pgv->joyRange.jpMax.dw##a; \
} else if( pji->dw##a##pos < pgv->joyRange.jpMin.dw##a ) { \
pji->dw##a##pos = pgv->joyRange.jpMin.dw##a; \
} \
\
/* \
* fill the bar if we haven't moved since last time \
*/ \
if( pji->dw##a##pos != poji->dw##a##pos ) { \
fillBar( pgv, hwnd, pji->dw##a##pos, id ); \
poji->dw##a##pos = pji->dw##a##pos; \
}
/*
* DoJoyMove - process movement for the joystick
*/
void DoJoyMove( LPGLOBALVARS pgv, HWND hwnd, LPJOYINFOEX pji,
LPJOYINFOEX poji, DWORD drawflags )
{
HWND hwlb;
RECT rc;
int width;
int height;
DWORD x,y;
/*
* draw the cross in the XY box if needed
*/
if( drawflags & JOYMOVE_DRAWXY ) {
/*
* make sure we aren't out of alleged range
*/
if( pji->dwXpos > pgv->joyRange.jpMax.dwX ) {
pji->dwXpos = pgv->joyRange.jpMax.dwX;
} else if( pji->dwXpos < pgv->joyRange.jpMin.dwX ) {
pji->dwXpos = pgv->joyRange.jpMin.dwX;
}
if( pji->dwYpos > pgv->joyRange.jpMax.dwY ) {
pji->dwYpos = pgv->joyRange.jpMax.dwY;
} else if( pji->dwYpos < pgv->joyRange.jpMin.dwY ) {
pji->dwYpos = pgv->joyRange.jpMin.dwY;
}
/*
* convert info to (x,y) position in window
*/
hwlb = GetDlgItem( hwnd, IDC_JOYLIST1 );
GetClientRect( hwlb, &rc );
height = rc.bottom - rc.top-2*DELTA;
width = rc.right - rc.left-2*DELTA;
x = ADJ_VAL( X, pji->dwXpos, width ) + DELTA;
y = ADJ_VAL( Y, pji->dwYpos, height ) + DELTA;
/*
* only draw the cross if it has moved since last time
*/
if( x != (DWORD) poji->dwXpos || y != (DWORD) poji->dwYpos ) {
if( poji->dwXpos != (DWORD) -1 ) {
// drawCross( hwlb, (int) poji->dwXpos, (int) poji->dwYpos, WHITE_PEN );
drawCross( hwlb, (int) poji->dwXpos, (int) poji->dwYpos, -1 );
}
drawCross( hwlb, (int) x, (int) y, BLACK_PEN );
poji->dwXpos = x;
poji->dwYpos = y;
}
}
/*
* draw Z bar if needed
*/
if( drawflags & JOYMOVE_DRAWZ ) {
FILLBAR( Z, IDC_JOYLIST2 );
}
/*
* draw R bar if needed
*/
if( drawflags & JOYMOVE_DRAWR ) {
FILLBAR( R, IDC_JOYLIST3 );
}
/*
* draw U bar if needed
*/
if( drawflags & JOYMOVE_DRAWU ) {
FILLBAR( U, IDC_JOYLIST4 );
}
/*
* draw V bar if needed
*/
if( drawflags & JOYMOVE_DRAWV ) {
FILLBAR( V, IDC_JOYLIST5 );
}
} /* DoJoyMove */