Я оптимизирую класс, выполненный в Visual Studios 2012, который обнаруживает сенсорные события и рисует круги под вашими пальцами, чтобы отследить, где вы касаетесь вдоль окна. Класс работал нормально, когда все было написано в одном .cpp
файл. Наш профессор хочет, чтобы мы привыкли делать все объекты объектно-ориентированными, чтобы наш код был аккуратным и читабельным. Я закончил настройку, и когда я его запускаю, программа не выдаёт мне ошибок или предупреждений, что хорошо, но приложение не рисует на экране ничего, как раньше.
Вот код:
Заголовочный файл:
#include <windows.h> // for windows touch
#include "RawTouchData.h" //library class that I created
#include <string.h>
#include <tchar.h>
using namespace std;
class BaseClass
{
public:
HINSTANCE hInst;
rtd::UINT cInputs;
rtd::PTOUCHINPUT pInputs;
rtd::POINT ptInput;
//Maximum ammount of touches allowed
#define MAXPOINTS 10
COLORREF colors[9];
//Instancing the handler
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
// You will use this array to track touch points
int points[MAXPOINTS][2];
// You will use this array to switch the color / track ids
int idLookup[MAXPOINTS];
// You can make the touch points larger
// by changing this radius value
int radius;
int wmId, wmEvent, i, x, y, index;
// This function is used to return an index given an ID
int GetContactIndex(int dwID);
//ctor
BaseClass(void);
protected:
virtual ~BaseClass(void);
private:
HWND m_hwnd;
};
Исходный файл:
#include "BaseClass.h"
//ctor
BaseClass::BaseClass(){
colors[0] = RGB(220,20,60);
colors[1] = RGB(128,0,128);
colors[2] = RGB(0,0,255);
colors[3] = RGB(0,206,209);
colors[4] = RGB(0,201,87);
colors[5] = RGB(0,255,0);
colors[6] = RGB(255,255,0);
colors[7] = RGB(255, 128, 255);
colors[8] = RGB(153,153,255);
colors[9] = RGB(0,51,153);
radius = 30;
wmId = 0,
wmEvent = 0,
i = 0,
x = 0,
y = 0,
index = 0;
}
//dtor
BaseClass::~BaseClass(){
}
// This function is used to return an index given an ID
int BaseClass::GetContactIndex(int dwID){
BaseClass *ptr_bc = new BaseClass();//ptr baseclass
for (int i=0; i < MAXPOINTS; i++){
if (ptr_bc->idLookup[i] == -1){
ptr_bc->idLookup[i] = dwID;
return i;
}else{
if (ptr_bc->idLookup[i] == dwID){
return i;
}
}
}
// Out of contacts
return -1;
}
// Provides the application entry point.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcex;
BaseClass *ptr_bc = new BaseClass();//ptr
ptr_bc->GetScreenResolution(width, height);
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = BaseClass::WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"win32app";// The main window class name.
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL,
_T("Call to RegisterClassEx failed!"),
_T("Win32 Guided Tour"),
NULL);
return 1;
}
ptr_bc->hInst = hInstance; // Store instance handle in our global variable
// The parameters to CreateWindow explained:
// szWindowClass: the name of the application
// szTitle: the text that appears in the title bar
// WS_OVERLAPPEDWINDOW: the type of window to create
// CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
// 500, 100: initial size (width, length)
// NULL: the parent of this window
// NULL: this application does not have a menu bar
// hInstance: the first parameter from WinMain
// NULL: not used in this application
HWND hWnd = CreateWindow(
L"win32app",
L"Hello World!",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
800, 600,
NULL,
NULL,
hInstance,
NULL
);
if (!hWnd) {
MessageBox(NULL,
_T("Call to CreateWindow failed!"),
_T("Win32 Guided Tour"),
NULL);
return 1;
}
// register the window for touch instead of gestures
rtd::RegisterTouchWindow(hWnd, 0);
// the following code initializes the points
for (int i=0; i< MAXPOINTS; i++){
ptr_bc->points[i][0] = -1;
ptr_bc->points[i][1] = -1;
ptr_bc->idLookup[i] = -1;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// Main message loop:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes touch messages for the main window.
//
// WM_TOUCH - handles WM_TOUCH messages in the application
// WM_PAINT - handles what is being drawn on the screen
// WM_DESTROY - post a quit message and return
//
LRESULT CALLBACK BaseClass::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
BaseClass *pptr_bc = new BaseClass();//ptr
// For double buffering
static HDC memDC = 0;
static HBITMAP hMemBmp = 0;
HBITMAP hOldBmp = 0;
//For drawing / fills
PAINTSTRUCT ps;
HDC hdc;
HBRUSH whiteBrush, toucPointBrushes;
switch (message)
{
case WM_TOUCH:
//LOWORD(wParam) = number of touch points in this message
//HIWORD(wParam) = reserved for future use
//lParam = handle for use with GetTouchInputInfo
pptr_bc->cInputs = LOWORD(wParam);
pptr_bc->pInputs = new rtd::TOUCHINPUT[ pptr_bc->cInputs ];
if(pptr_bc->pInputs)
{
if( rtd::GetTouchInputInfo((rtd::HTOUCHINPUT)lParam, pptr_bc->cInputs, pptr_bc->pInputs, sizeof(rtd::TOUCHINPUT)) )
{
for (int i=0; i < static_cast<INT>(pptr_bc->cInputs); i++)
{
rtd::TOUCHINPUT ti = pptr_bc->pInputs[i];
pptr_bc->index = pptr_bc->GetContactIndex(ti.dwID);
if(ti.dwID != 0 && pptr_bc->index < MAXPOINTS )
{
//get screen corrdinates of touch
pptr_bc->ptInput.x = TOUCH_COORD_TO_PIXEL(ti.x);
pptr_bc->ptInput.y = TOUCH_COORD_TO_PIXEL(ti.y);
//get coordinates relative to the top left of the application window
ScreenToClient(hWnd, &pptr_bc->ptInput);
if(ti.dwFlags & TOUCHEVENTF_UP)
{
pptr_bc->points[pptr_bc->index][0] = -1;
pptr_bc->points[pptr_bc->index][1] = -1;
}
else
{
pptr_bc->points[pptr_bc->index][0] = pptr_bc->ptInput.x;
pptr_bc->points[pptr_bc->index][1] = pptr_bc->ptInput.y;
}
}
}
}
rtd::CloseTouchInputHandle((rtd::HTOUCHINPUT)lParam);
delete [] pptr_bc->pInputs;
}
InvalidateRect(hWnd, NULL, FALSE);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT client;
GetClientRect(hWnd, &client);
//START DOUBLE BUFFERING
if (!memDC)
{
memDC = CreateCompatibleDC(hdc);
}
hMemBmp = CreateCompatibleBitmap(hdc, client.right, client.bottom);
hOldBmp = (HBITMAP)SelectObject(memDC, hMemBmp);
//draws the white background
whiteBrush = CreateSolidBrush(RGB(255,255,255));
//paints the packdrop
FillRect(memDC, &client, whiteBrush);
//Draw Touched Points
for (pptr_bc->i=0; pptr_bc->i < MAXPOINTS; pptr_bc->i++)
{
toucPointBrushes = CreateSolidBrush(pptr_bc->colors[pptr_bc->i]);
SelectObject( memDC, toucPointBrushes);
pptr_bc->x = pptr_bc->points[pptr_bc->i][0];
pptr_bc->y = pptr_bc->points[pptr_bc->i][1];
if (pptr_bc->x >0 && pptr_bc->y>0)
{
Ellipse(memDC, pptr_bc->x - pptr_bc->radius, pptr_bc->y - pptr_bc->radius, pptr_bc->x + pptr_bc->radius, pptr_bc->y + pptr_bc->radius);
}
DeleteObject(toucPointBrushes); //when i am not using the brushes
}
BitBlt(hdc, 0,0, client.right, client.bottom, memDC, 0,0, SRCCOPY);
DeleteObject(whiteBrush);//when I am not using the background
EndPaint(hWnd, &ps);
DeleteObject(hMemBmp); // prevents memory leak
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Вот файл RawTouchData:
#ifndef RAWTOUCHDATA_H
#define RAWTOUCHDATA_H
#pragma once
//#define __in __allowed(on_parameter)
#if (defined(_M_IX86) || defined(_M_IA64) || defined(_M_AMD64)) && !defined(MIDL_PASS)
#define DECLSPEC_IMPORT __declspec(dllimport)
#else
#define DECLSPEC_IMPORT
#endif
//
// Define API decoration for direct importing of DLL references.
//
#if !defined(_USER32_)
#define WINUSERAPI DECLSPEC_IMPORT
#define WINABLEAPI DECLSPEC_IMPORT
#else
#define WINUSERAPI
#define WINABLEAPI
#endif
#ifndef NO_STRICT
#ifndef STRICT
#define STRICT 1
#endif
#endif /* NO_STRICT */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifndef WINVER // Specifies that the minimum required platform is Windows 7.
#define WINVER 0x0601 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows 7.
#define _WIN32_WINNT 0x0601 // Change this to the appropriate value to target other versions of Windows.
#endif
//
// The following types are guaranteed to be signed and 32 bits wide.
//
typedef signed int LONG32, *PLONG32;
//
// The following types are guaranteed to be unsigned and 32 bits wide.
//
typedef unsigned int ULONG32, *PULONG32;
typedef unsigned int DWORD32, *PDWORD32;
#if !defined(_W64)
#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
#define _W64 __w64
#else
#define _W64
#endif
#endif
//
// The INT_PTR is guaranteed to be the same size as a pointer. Its
// size with change with pointer size (32/64). It should be used
// anywhere that a pointer is cast to an integer type. UINT_PTR is
// the unsigned variation.
//
// __int3264 is intrinsic to 64b MIDL but not to old MIDL or to C compiler.
//
#if ( 501 < __midl )
typedef [public] __int3264 INT_PTR, *PINT_PTR;
typedef [public] unsigned __int3264 UINT_PTR, *PUINT_PTR;
typedef [public] __int3264 LONG_PTR, *PLONG_PTR;
typedef [public] unsigned __int3264 ULONG_PTR, *PULONG_PTR;
#else // midl64
// old midl and C++ compiler
#if defined(_WIN64)
typedef __int64 INT_PTR, *PINT_PTR;
typedef unsigned __int64 UINT_PTR, *PUINT_PTR;
typedef __int64 LONG_PTR, *PLONG_PTR;
typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
#define __int3264 __int64
#else
typedef _W64 int INT_PTR, *PINT_PTR;
typedef _W64 unsigned int UINT_PTR, *PUINT_PTR;
typedef _W64 long LONG_PTR, *PLONG_PTR;
typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
#define __int3264 __int32
#endif
#endif // midl64
//
// Define API decoration for direct importing system DLL references.
//
#if !defined(_NTSYSTEM_)
#define NTSYSAPI DECLSPEC_IMPORT
#define NTSYSCALLAPI DECLSPEC_IMPORT
#else
#define NTSYSAPI
#if defined(_NTDLLBUILD_)
#define NTSYSCALLAPI
#else
#define NTSYSCALLAPI DECLSPEC_ADDRSAFE
#endif
#endif
//
// Basics
//
#ifndef VOID
#define VOID void
typedef char CHAR;
typedef short SHORT;
typedef long LONG;
#if !defined(MIDL_PASS)
typedef int INT;
#endif
#endif
#ifndef WINVER
#define WINVER 0x0500
#endif /* WINVER */
/*
* BASETYPES is defined in ntdef.h if these types are already defined
*/
#ifndef BASETYPES
#define BASETYPES
typedef unsigned long ULONG;
typedef ULONG *PULONG;
typedef unsigned short USHORT;
typedef USHORT *PUSHORT;
typedef unsigned char UCHAR;
typedef UCHAR *PUCHAR;
typedef char *PSZ;
#endif /* !BASETYPES */
#define MAX_PATH 260
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef IN
#define IN
#endif
#ifndef OUT
#define OUT
#endif
#ifndef OPTIONAL
#define OPTIONAL
#endif
#undef far
#undef near
#undef pascal
#define far
#define near
#if (!defined(_MAC)) && ((_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED))
#define pascal __stdcall
#else
#define pascal
#endif
#if defined(DOSWIN32) || defined(_MAC)
#define cdecl _cdecl
#ifndef CDECL
#define CDECL _cdecl
#endif
#else
#define cdecl
#ifndef CDECL
#define CDECL
#endif
#endif
#ifdef _MAC
#define CALLBACK PASCAL
#define WINAPI CDECL
#define WINAPIV CDECL
#define APIENTRY WINAPI
#define APIPRIVATE CDECL
#ifdef _68K_
#define PASCAL __pascal
#else
#define PASCAL
#endif
#elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#define CALLBACK __stdcall
#define WINAPI __stdcall
#define WINAPIV __cdecl
#define APIENTRY WINAPI
#define APIPRIVATE __stdcall
#define PASCAL __stdcall
#else
#define CALLBACK
#define WINAPI
#define WINAPIV
#define APIENTRY WINAPI
#define APIPRIVATE
#define PASCAL pascal
#endif
#ifdef _M_CEE_PURE
#define WINAPI_INLINE __clrcall
#else
#define WINAPI_INLINE WINAPI
#endif
#undef FAR
#undef NEAR
#define FAR far
#define NEAR near
#ifndef CONST
#define CONST const
#endif
namespace rtd //Raw Touch Data
{
typedef unsigned long DWORD;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef float FLOAT;
typedef FLOAT *PFLOAT;
typedef BYTE near *PBYTE;
typedef BYTE far *LPBYTE;
typedef int near *PINT;
typedef int far *LPINT;
typedef WORD near *PWORD;
typedef WORD far *LPWORD;
typedef long far *LPLONG;
typedef DWORD near *PDWORD;
typedef DWORD far *LPDWORD;
typedef void far *LPVOID;
typedef CONST void far *LPCVOID;
typedef int INT;
typedef unsigned int UINT;
typedef unsigned int *PUINT;
#if(WINVER >= 0x0601)
#define WM_TOUCH 0x0240
#endif /* WINVER >= 0x0601 */
typedef const RECTL FAR* LPCRECTL;
typedef struct tagPOINT
{
LONG x;
LONG y;
} POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;
typedef struct _POINTL /* ptl */
{
LONG x;
LONG y;
} POINTL, *PPOINTL;
typedef struct tagSIZE
{
LONG cx;
LONG cy;
} SIZE, *PSIZE, *LPSIZE;
typedef SIZE SIZEL;
typedef SIZE *PSIZEL, *LPSIZEL;
typedef struct tagPOINTS
{
#ifndef _MAC
SHORT x;
SHORT y;
#else
SHORT y;
SHORT x;
#endif
} POINTS, *PPOINTS, *LPPOINTS;
#if(WINVER >= 0x0601)
/*
* Touch Input defines and functions
*/
/*
* Touch input handle
*/
DECLARE_HANDLE(HTOUCHINPUT);
typedef struct tagTOUCHINPUT {
LONG x;
LONG y;
HANDLE hSource;
DWORD dwID;
DWORD dwFlags;
DWORD dwMask;
DWORD dwTime;
ULONG_PTR dwExtraInfo;
DWORD cxContact;
DWORD cyContact;
} TOUCHINPUT, *PTOUCHINPUT;
typedef TOUCHINPUT const * PCTOUCHINPUT;
/*
* Conversion of touch input coordinates to pixels
*/
#define TOUCH_COORD_TO_PIXEL(l) ((l) / 100)
/*
* Touch input flag values (TOUCHINPUT.dwFlags)
*/
#define TOUCHEVENTF_MOVE 0x0001
#define TOUCHEVENTF_DOWN 0x0002
#define TOUCHEVENTF_UP 0x0004
#define TOUCHEVENTF_INRANGE 0x0008
#define TOUCHEVENTF_PRIMARY 0x0010
#define TOUCHEVENTF_NOCOALESCE 0x0020
#define TOUCHEVENTF_PEN 0x0040
#define TOUCHEVENTF_PALM 0x0080
/*
* Touch input mask values (TOUCHINPUT.dwMask)
*/
#define TOUCHINPUTMASKF_TIMEFROMSYSTEM 0x0001 // the dwTime field contains a system generated value
#define TOUCHINPUTMASKF_EXTRAINFO 0x0002 // the dwExtraInfo field is valid
#define TOUCHINPUTMASKF_CONTACTAREA 0x0004 // the cxContact and cyContact fields are valid
WINUSERAPI
BOOL
WINAPI
ScreenToClient(
HWND hWnd,
LPPOINT lpPoint);
WINUSERAPI
BOOL
WINAPI
GetTouchInputInfo(
HTOUCHINPUT hTouchInput, // input event handle; from touch message lParam
UINT cInputs, // number of elements in the array
PTOUCHINPUT pInputs, // array of touch inputs
int cbSize); // sizeof(TOUCHINPUT)
WINUSERAPI
BOOL
WINAPI
CloseTouchInputHandle(
HTOUCHINPUT hTouchInput); // input event handle; from touch message lParam
/*
* RegisterTouchWindow flag values
*/
#define TWF_FINETOUCH (0x00000001)
#define TWF_WANTPALM (0x00000002)
WINUSERAPI
BOOL
WINAPI
RegisterTouchWindow(
HWND hwnd,
ULONG ulFlags);
WINUSERAPI
BOOL
WINAPI
UnregisterTouchWindow(
HWND hwnd);
WINUSERAPI
BOOL
WINAPI
IsTouchWindow(
HWND hwnd,
PULONG pulFlags);
#endif /* WINVER >= 0x0601 */
#ifdef __cplusplus
}
#endif /* __cplusplus */
}
#endif //RAWTOUCHDATA_H
Если кто-нибудь сможет поймать то, что я пропустил, я был бы очень признателен. Заранее благодарю!
Задача ещё не решена.
Других решений пока нет …