/////////////////////////////////////////////////////////////////////////////// // // mousectl.c // // // History: // 11 May 95 SteveCat // Ported to Windows NT and Unicode, cleaned up // // // NOTE/BUGS // // Copyright (C) 1994-1995 Microsoft Corporation // /////////////////////////////////////////////////////////////////////////////// //========================================================================== // Include files //========================================================================== #include "main.h" #include "mousectl.h" #include "rc.h" //------------------------------------------------------------------------------ #define LocalLockPtr( lp ) \ ((BOOL)SELECTOROF( LocalLock( LocalHandle( lp )))) #define LocalUnlockPtr( lp ) \ LocalUnlock( LocalHandle( lp )) #define LocalAllocPtr( flags, cb ) \ (LocalLock( LocalAlloc((flags ), (cb )))) #define LocalFreePtr( lp ) \ (LocalUnlockPtr( lp ), (BOOL)LocalFree( LocalHandle( lp ))) //------------------------------------------------------------------------------ #define MOUSECTL_BITMAP_NAME MAKEINTRESOURCE( IDB_MOUSE ) #define MOUSECTL_DATA 0 // these are indices into the VGA palette! #define MOUSECTL_BKGND_INDEX 14 // light cyan #define MOUSECTL_LBUTTON_INDEX 13 // light magenta #define MOUSECTL_RBUTTON_INDEX 11 // light yellow #define MOUSECTL_LBUTTON_ALTERNATE 5 // magenta #define MOUSECTL_RBUTTON_ALTERNATE 3 // yellow #define MOUSECTL_NORMAL_COLOR RGB( 255, 255, 255 ) #define HALFRGB( c ) RGB( GetRValue( c )/2, GetGValue( c )/2, GetBValue( c )/2 ) //------------------------------------------------------------------------------ typedef struct tagMOUSECTLDATA { HWND window; // window handle for this control BOOL swapped; // are the buttons swapped? HBITMAP image; // DIB section image of mouse HDC imagedc; // DC where image lives HBITMAP olddcimage; // previous inhabitant of imagedc POINT offset; // offset of bitmap in control SIZE size; // size of bitmap } MOUSECTLDATA, *PMOUSECTLDATA; //------------------------------------------------------------------------------ PMOUSECTLDATA CreateMouseControlData( HWND ); void DestroyMouseControlData( PMOUSECTLDATA ); LRESULT CALLBACK MouseControlWndProc( HWND, UINT, WPARAM, LPARAM ); BOOL MouseControlNCCreate( PMOUSECTLDATA, LPCREATESTRUCT ); void MouseControlNCDestroy( PMOUSECTLDATA ); void MouseControlPaint( PMOUSECTLDATA ); void MouseControlRBUp( PMOUSECTLDATA, int, int, UINT ); void MouseControlShowSwap( PMOUSECTLDATA ); //------------------------------------------------------------------------------ __inline void SetMouseControlData( HWND window, PMOUSECTLDATA ctldata ) { SetWindowLong( window, MOUSECTL_DATA, (LONG)ctldata ); } __inline PMOUSECTLDATA GetMouseControlData( HWND window ) { return (PMOUSECTLDATA)GetWindowLong( window, MOUSECTL_DATA ); } //------------------------------------------------------------------------------ BOOL RegisterMouseControlStuff( HINSTANCE instance ) { WNDCLASS wc; wc.style = 0; wc.lpfnWndProc = MouseControlWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = sizeof( LONG ); wc.hInstance = instance; wc.hIcon = NULL; wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hbrBackground = (HBRUSH)( COLOR_BTNFACE + 1 ); wc.lpszMenuName = NULL; wc.lpszClassName = MOUSECTL_CLASSNAME; return RegisterClass( &wc ); } //------------------------------------------------------------------------------ PMOUSECTLDATA CreateMouseControlData( HWND window ) { PMOUSECTLDATA ctldata = (PMOUSECTLDATA) LocalAllocPtr( LHND, sizeof( MOUSECTLDATA ) ); if( ctldata ) { ctldata->window = window; SetMouseControlData( window, ctldata ); } return ctldata; } void DestroyMouseControlData( PMOUSECTLDATA ctldata ) { if( ctldata ) { SetMouseControlData( ctldata->window, 0 ); LocalFreePtr( ctldata ); } } //------------------------------------------------------------------------------ LRESULT CALLBACK MouseControlWndProc( HWND window, UINT message, WPARAM wParam, LPARAM lParam ) { PMOUSECTLDATA ctldata = ( message == WM_NCCREATE ) ? CreateMouseControlData( window ) : GetMouseControlData( window ); switch( message ) { // this used to handle more messages which justified a custom control HANDLE_MSG( ctldata, WM_NCCREATE, MouseControlNCCreate ); HANDLE_MSG( ctldata, WM_NCDESTROY, MouseControlNCDestroy ); HANDLE_MSG( ctldata, WM_PAINT, MouseControlPaint ); } return DefWindowProc( window, message, wParam, lParam ); } BOOL MouseControlNCCreate( PMOUSECTLDATA ctldata, LPCREATESTRUCT cs ) { if( !ctldata ) return FALSE; ctldata->image = LoadImage( cs->hInstance, MOUSECTL_BITMAP_NAME, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION ); if( ctldata->image ) { ctldata->imagedc = CreateCompatibleDC( NULL ); if( ctldata->imagedc ) { BITMAP bm; ctldata->olddcimage = SelectBitmap( ctldata->imagedc, ctldata->image ); ctldata->offset.x = ctldata->offset.y = 0; if( GetObject( ctldata->image, sizeof( BITMAP ), &bm ) ) { ctldata->size.cx = bm.bmWidth; ctldata->size.cy = bm.bmHeight; ctldata->offset.x = ( cs->cx - ctldata->size.cx ) / 2; ctldata->offset.y = ( cs->cy - ctldata->size.cy ) / 2; ctldata->swapped = FALSE; MouseControlShowSwap( ctldata ); return TRUE; } SelectBitmap( ctldata->imagedc, ctldata->olddcimage ); ctldata->olddcimage = NULL; } DeleteBitmap( ctldata->image ); ctldata->image = NULL; } ctldata->olddcimage = NULL; ctldata->imagedc = NULL; return FALSE; } void MouseControlNCDestroy( PMOUSECTLDATA ctldata ) { if( ctldata ) { if( ctldata->olddcimage ) { SelectBitmap( ctldata->imagedc, ctldata->olddcimage ); ctldata->olddcimage = NULL; } if( ctldata->imagedc ) { DeleteDC( ctldata->imagedc ); ctldata->imagedc = NULL; } if( ctldata->image ) { DeleteBitmap( ctldata->image ); ctldata->image = NULL; } DestroyMouseControlData( ctldata ); } } void MouseControlPaint( PMOUSECTLDATA ctldata ) { PAINTSTRUCT ps; HDC dc = BeginPaint( ctldata->window, &ps ); BitBlt( dc, ctldata->offset.x, ctldata->offset.y, ctldata->size.cx, ctldata->size.cy, ctldata->imagedc, 0, 0, SRCCOPY ); EndPaint( ctldata->window, &ps ); } __inline void MouseControlSetColor( PMOUSECTLDATA ctldata, UINT index, COLORREF color ) { RGBQUAD rgbq = { GetBValue( color ), GetGValue( color ), GetRValue( color ), 0 }; SetDIBColorTable( ctldata->imagedc, index, 1, &rgbq ); } void MouseControlShowSwap( PMOUSECTLDATA ctldata ) { MouseControlSetColor( ctldata, MOUSECTL_BKGND_INDEX, GetSysColor( COLOR_BTNFACE ) ); MouseControlSetColor( ctldata, ctldata->swapped ? MOUSECTL_RBUTTON_INDEX : MOUSECTL_LBUTTON_INDEX, GetSysColor( COLOR_HIGHLIGHT ) ); MouseControlSetColor( ctldata, ctldata->swapped ? MOUSECTL_RBUTTON_ALTERNATE : MOUSECTL_LBUTTON_ALTERNATE, HALFRGB( GetSysColor( COLOR_HIGHLIGHT ) ) ); MouseControlSetColor( ctldata, ctldata->swapped? MOUSECTL_LBUTTON_INDEX : MOUSECTL_RBUTTON_INDEX, MOUSECTL_NORMAL_COLOR ); MouseControlSetColor( ctldata, ctldata->swapped? MOUSECTL_LBUTTON_ALTERNATE : MOUSECTL_RBUTTON_ALTERNATE, HALFRGB( MOUSECTL_NORMAL_COLOR ) ); InvalidateRect( ctldata->window, NULL, FALSE ); } void MouseControlSetSwap( HWND window, BOOL swap ) { PMOUSECTLDATA ctldata = GetMouseControlData( window ); if( ctldata->swapped != swap ) { ctldata->swapped = swap; MouseControlShowSwap( ctldata ); } }