What does this code do?
This code shows one way of using the additional information provided by digitising tablets in an MFC application.
Graphics or digitising tablets, which use a pen or a puck provide more information than a mouse pointer. They provide a direction that the pointer is rotated about it’s central point and the pressure with which the pointer is pressing on the pad. Some tablets also provide the angle between the pen and the tablet surface and a cursor number depending on a button pressed or orientation of the pen. All of these are essential in a drawing application to give a good feel to the results, but are also useful to add that little extra in other applications, for speed of an action based on the pressure or direction of movement based on the direction of the pen. What you use it for is up to you.
This code requires the ‘WinTab‘ libraries available from the following:
The example programme provided just moves a cross hair about the screen and displays the numeric information for pressure, tilt and direction, etc. In addition it changes the colour of a dot that changes size based on the pressure on the tablet, and colour based on the cursor number.
How do I integrate it with my existing code?
The example provided is based on CView, but any class derived from CCmdTarget should work. I have split each part in to a separate member function which could be easily created in your new application. Only about 4 member functions need to be created (and a few member variables) to get going, but some of the other functions may be useful.
You will need to download and include the ‘WinTab‘ libraries and headers in your application. More details are included in the comments within the code. The provided executable, should, run without any additions, but will only show something useful, if you have a graphics tablet installed. (This also assumes the make of graphics tablet you have uses the ‘WinTab‘ interface, see if you have /Windows/System/wintab32.dll installed.))
The idea was to create an example rather than a building block, but it would be easy to create a CView class with the code built in. You could then replace the CView class created in any new application.
Is there any similar code?
Before I started on this example I hunted round the web, on manufacturers and developer sites and found no reference to code for using graphics tablets in applications. I did, however, find the ‘WinTab’ library. This ‘WinTab’ library is the foundation for using graphics tablets on any machine, and provides a standard application interface. I still could not find any good examples of actually using these libraries. The few I found, either would not compile or took control of the mouse pointer messing up other applications running at the same time. (If anyone has some other good examples please e-mail me the URLs, thanks.)
All I wanted was to get the extra information provided by the tablet. The pointer location and button information is already provided by the standard mouse driver, so I didn’t need to interfere with that. This code tries to avoid anything already provided by the mouse and deliberately not interfere with the mouse pointer functions.
Where do I look in the code?
I have tried to fully document the code in the comments but some areas to look at in more detail:
The exact information provided by the packet MUST be defined first. The ‘WinTab‘ libraries provide a header file ‘pktdef.h’ to create a packet definition depending on what information you require. Only that definition can be used throughout your app to ensure the packet structure is consistent.
In your header file:
#define PACKETDATA (PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR)
#define PACKETMODE 0
The include files and the packet definition, must be in this order and must be in the header file. If you want to change the information provided by the tablet packet you must change the PACKETDATA definition and change your code to extract that extra information from the packet.
The example code only uses: Pressure (PK_NORMAL_PRESSURE), Tilt and Direction (PK_ORIENTATION) and the cursor number (PK_CURSOR). Everything else is already provided by the mouse driver.
Next you need to capture the tablet packet message:
and in the header:
//TABLET: Tablet messages
ON_MESSAGE( WT_PACKET, PrgTabTest::OnTabPacket )
//TABLET: end tablet messages
afx_msg void OnTabPacket(WPARAM wParam, LPARAM lParam);
Now the tablet context must be initialised for the application to start receiving tablet messages:
HCTX PrgTabTest::InitTablet(HWND hWnd)
LOGCONTEXT lcMine; // The context of the tablet
WTInfo(WTI_DEFSYSCTX, 0, &lcMine); // get the current settings as set in control panel
lcMine.lcOptions |= CXO_MESSAGES; // make sure messages are on
lcMine.lcPktData = PACKETDATA; // this is where those packet definitions are used
lcMine.lcPktMode = PACKETMODE;
lcMine.lcMoveMask = PACKETDATA;
return WTOpen(hWnd, &lcMine, TRUE);
Now that the application is receiving packets, the example application shows one way of using them. See the
void PrgTabTest::OnTabPacket(WPARAM wParam, LPARAM lParam)
members for more details.
BOOL PrgTabTest::GetTabState(LPARAM lParam, WPARAM wParam, UINT & nTabPressure, int & nTabAltitude, int & nTabTwist, int & nTabCompass, UINT & nTabCursor)
The example is now the best place to look for further information.
Does the code work under UNICODE?
I have no idea, I don't see why it shouldn't but I haven't checked.
What version of MFC was the code built with?
I am using Visual C++ 5, which uses MFC version 4.21 (I think). It doesn't use anything fancy, so it should compile under earlier versions of MFC 4 and hopefully future versions.
I spent some time unravelling how the 'WinTab' libraries actually worked so I may be able to help with some questions, but mainly I had to use experimentation to get it to work. If you have any questions, comments or improvements, please e-mail me.
Date Posted: 12 September 1998