我的屏幕绘制不正确

时间:2013-11-21 17:17:35

标签: c++ visual-studio pointers wndproc

我正在优化在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

如果有人能抓住我错过的东西,我将非常感激。先谢谢你了!

0 个答案:

没有答案