DXライブラリでタブレットの筆圧感知を取得したい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Tangeθ

DXライブラリでタブレットの筆圧感知を取得したい

#1

投稿記事 by Tangeθ » 9年前

DXライブラリでワコムの筆圧を取得したいのですが、やり方がよく分かりません。
ttp://wdnet.jp/library/windows
↑のサイトの『筆圧テスト』の項目を参考にすれば良いとは分かって、どうやらWTPacket関数で筆圧を取得すれば良いのだろうということまではなんとなく分かりました。
しかし、DXライブラリでWPARAMやLPARAMなど(というかプロシージャ自体も)使いませんし、下のコードをコンパイルしてもエラーが出てしまいます。エラーリンカ2019なので、extern宣言しかしていないでしょうか?

エラー 4 error LNK2019: 未解決の外部シンボル _WTPacket@12 が関数 _WinMain@16 で参照されました。 main.obj
エラー 5 fatal error LNK1120: 外部参照 1 が未解決です。 c:\Users\ユーザー名\Desktop\プロジェクト名\obj\Release\テスト.exe

以下、コードです

コード:

#include <DxLib.h>
#include "msgpack.h"
#include "wintab.h"
#define PACKETDATA	(PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE)
#define PACKETMODE	PK_BUTTONS
#include "pktdef.h"


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
				 LPSTR lpCmdLine, int nCmdShow )
{
	PACKET pkt;
	
	ChangeWindowMode( TRUE ) ;

	if( DxLib_Init() == -1 )	// DXライブラリ初期化処理
	{
		 return -1;				// エラーが起きたら直ちに終了
	}
	SetMouseDispFlag( TRUE );

	while( ProcessMessage() == 0  )
    {
	ClsDrawScreen();
	WPARAM wParam=0;// ここよく分かりません
	LPARAM lParam=0;// ここよく分かりません
	WTPacket((HCTX)lParam, wParam, &pkt);
	UINT size=pkt.pkNormalPressure;
	clsDx();printfDx("%d",size);

	
	ScreenFlip();
	}

	DxLib_End() ;				// DXライブラリ使用の終了処理

	return 0 ;					// ソフトの終了
}

なお、WTPacketの部分をサンプルプログラム内に記載してあるgpWTPacketに変えた場合、以下のエラーでコンパイル出来ませんでした。

エラー 2 error C3861: 'gpWTPacket': 識別子が見つかりませんでした c:\Users\ユーザー名\Desktop\プロジェクト名\source\ディレクトリ\main.cpp 27

環境  
  OS : Windows7 64bit
  コンパイラ名 : VC++ 2008

これはどうすれば、筆圧が取得できるのでしょうか?教えて下さい。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: DXライブラリでタブレットの筆圧感知を取得したい

#2

投稿記事 by h2so5 » 9年前

サンプルプログラムを見てみましたがそんなに簡単にはできないように思われます。
ペンタブの初期化処理なども必要になってくるのと、DXライブラリのウィンドウメッセージの処理を自前で行う必要があります。
自分はタブレットを持ってないので試せないんですが。

Tangeθ

Re: DXライブラリでタブレットの筆圧感知を取得したい

#3

投稿記事 by Tangeθ » 9年前

h2so5さん返信ありがとうございます。

>>サンプルプログラムを見てみましたがそんなに簡単にはできないように思われます。

そうですか・・・出来たとしても時間とリソースが多く必要になりそうですね。今の所どちらも私にはないので、とりあえずは、筆圧感知なしでアプリケーションの開発を進めてみます。
ありがとうございました。

ISLe()

Re: DXライブラリでタブレットの筆圧感知を取得したい

#4

投稿記事 by ISLe() » 9年前

簡単そうに見えたので移植してみました。
タブレット関連のコードはそのまんまですし、エラー処理などもいいかげんで、とりあえず動くようにしてみただけといったものですが。

PRSTEST.Cを以下のものに差し替えてUtils.cと一緒にコンパイルしてください。

コード:

#include "DxLib.h"
#include <windowsx.h>
#include "wintab.h"
#define PACKETDATA	(PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE)
#define PACKETMODE	PK_BUTTONS
#include "pktdef.h"
extern "C" {
#include "Utils.h"
}

static HANDLE hInst = NULL;

char* gpszProgramName = "DXPRSTEST";
static LOGCONTEXT glogContext = {0};

static HCTX hCtx = NULL;

static HCTX TabletInit(HWND hWnd);
static LRESULT CALLBACK DxMainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

static POINT ptNew;
static UINT prsNew;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	hInst = hInstance;

	if (!LoadWintab()) return 0;
	if (!gpWTInfoA(0, 0, NULL)) goto L_exit_wt;

	ChangeWindowMode(TRUE);
	if (DxLib_Init() != 0) return 0;
	SetDrawScreen(DX_SCREEN_BACK);

	hCtx = TabletInit(GetMainWindowHandle());
	if (!hCtx) goto L_exit_dx;

	SetHookWinProc(DxMainWndProc);

	// 初回アクティブ化
	gpWTEnable(hCtx, TRUE);
	gpWTOverlap(hCtx, TRUE);

	while (ProcessMessage() == 0 && ScreenFlip() == 0 && ClearDrawScreen() == 0) {
		POINT scrPoint = { ptNew.x, ptNew.y };
		ScreenToClient(GetMainWindowHandle(), &scrPoint);
		DrawCircle(scrPoint.x, scrPoint.y, prsNew, GetColor(127,127,127), TRUE);
		DrawLine(0, scrPoint.y, 640, scrPoint.y, GetColor(255,255,255));
		DrawLine(scrPoint.x, 0, scrPoint.x, 480, GetColor(255,255,255));
	}

	gpWTClose(hCtx);

L_exit_dx:
	DxLib_End();

L_exit_wt:
	UnloadWintab();
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
static HCTX TabletInit(HWND hWnd)
{
	HCTX hctx = NULL;
	UINT wDevice = 0;
	UINT wExtX = 0;
	UINT wExtY = 0;
	UINT wWTInfoRetVal = 0;
	AXIS TabletX = {0};
	AXIS TabletY = {0};

	// Set option to move system cursor before getting default system context.
	glogContext.lcOptions |= CXO_SYSTEM;

	// Open default system context so that we can get tablet data
	// in screen coordinates (not tablet coordinates).
	wWTInfoRetVal = gpWTInfoA(WTI_DEFSYSCTX, 0, &glogContext);
	WACOM_ASSERT( wWTInfoRetVal == sizeof( LOGCONTEXT ) );

	WACOM_ASSERT( glogContext.lcOptions & CXO_SYSTEM );

	// modify the digitizing region
	wsprintf(glogContext.lcName, "PrsTest Digitizing %x", hInst);

	// We process WT_PACKET (CXO_MESSAGES) messages.
	glogContext.lcOptions |= CXO_MESSAGES;

	// What data items we want to be included in the tablet packets
	glogContext.lcPktData = PACKETDATA;

	// Which packet items should show change in value since the last
	// packet (referred to as 'relative' data) and which items
	// should be 'absolute'.
	glogContext.lcPktMode = PACKETMODE;

	// This bitfield determines whether or not this context will receive
	// a packet when a value for each packet field changes.  This is not
	// supported by the Intuos Wintab.  Your context will always receive
	// packets, even if there has been no change in the data.
	glogContext.lcMoveMask = PACKETDATA;

	// Which buttons events will be handled by this context.  lcBtnMask
	// is a bitfield with one bit per button.
	glogContext.lcBtnUpMask = glogContext.lcBtnDnMask;

	// Set the entire tablet as active
	wWTInfoRetVal = gpWTInfoA( WTI_DEVICES + 0, DVC_X, &TabletX );
	WACOM_ASSERT( wWTInfoRetVal == sizeof( AXIS ) );

	wWTInfoRetVal = gpWTInfoA( WTI_DEVICES, DVC_Y, &TabletY );
	WACOM_ASSERT( wWTInfoRetVal == sizeof( AXIS ) );

	glogContext.lcInOrgX = 0;
	glogContext.lcInOrgY = 0;
	glogContext.lcInExtX = TabletX.axMax;
	glogContext.lcInExtY = TabletY.axMax;

	// Guarantee the output coordinate space to be in screen coordinates.  
	glogContext.lcOutOrgX = GetSystemMetrics( SM_XVIRTUALSCREEN );
	glogContext.lcOutOrgY = GetSystemMetrics( SM_YVIRTUALSCREEN );
	glogContext.lcOutExtX = GetSystemMetrics( SM_CXVIRTUALSCREEN ); //SM_CXSCREEN );

	// In Wintab, the tablet origin is lower left.  Move origin to upper left
	// so that it coincides with screen origin.
	glogContext.lcOutExtY = -GetSystemMetrics( SM_CYVIRTUALSCREEN );	//SM_CYSCREEN );

	// Leave the system origin and extents as received:
	// lcSysOrgX, lcSysOrgY, lcSysExtX, lcSysExtY

	// open the region
	// The Wintab spec says we must open the context disabled if we are 
	// using cursor masks.  
	hctx = gpWTOpenA( hWnd, &glogContext, FALSE );

	WacomTrace("HCTX: %i\n", hctx);

	return hctx;

}

///////////////////////////////////////////////////////////////////////////////
static LRESULT CALLBACK DxMainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	PACKET pkt;

	switch (uMsg)
	{
	case WT_PACKET:
		if (gpWTPacket((HCTX)lParam, wParam, &pkt)) 
		{
			if (HIWORD(pkt.pkButtons)==TBN_DOWN) 
			{
				MessageBeep(0);
			}

			ptNew.x = pkt.pkX;
			ptNew.y = pkt.pkY;
			prsNew = pkt.pkNormalPressure;

		}
		break;

	case WM_ACTIVATE:
		/* if switching in the middle, disable the region */
		if (hCtx) {
			gpWTEnable(hCtx, GET_WM_ACTIVATE_STATE(wParam, lParam));
			if (hCtx && GET_WM_ACTIVATE_STATE(wParam, lParam))
				gpWTOverlap(hCtx, TRUE);
		}
		break;
	}
	return 0;
}

Tangeθ

Re: DXライブラリでタブレットの筆圧感知を取得したい

#5

投稿記事 by Tangeθ » 9年前

ISLe()さん返信ありがとうございます。
お陰で無事、コンパイル成功し動作も確認できました。

ただ、cファイルをcppファイルにした後、↓のコードのextern部分を削除しないと私のパソコンではコンパイルが通りませんでしたので、一応、記載しておきます。

コード:

~~~~~
//extern "C" {
#include "Utils.h"
//}
~~~~~
あれから、1人でwinTab関連のサイトを見て、色々やってみたのですが、力量不足で結局出来ませんでした。
本当に回答して下さった方々の助言の賜物です。
皆様、本当にありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る