mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
301 lines
8.4 KiB
301 lines
8.4 KiB
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 );
|
|
}
|
|
}
|
|
|