Note that there are some explanatory texts on larger screens.

plurals
  1. POMy screen is not drawing correctly
    text
    copied!<p>I am optimizing a class done in Visual Studios 2012 that detects touch events and draws circles beneath your finger(s) to track where you are touching along the window. The class worked fine when it was all written in a single <code>.cpp</code> file. Our professor wants us to get into the habit of making everything object oriented to keep our code neat and readable. I finished setting everything up and when I run it the program doesn't give me any errors or warnings, which is a good thing, but the application doesn't draw anything on the screen as it did before. </p> <p>Here is the code:</p> <p>The header file:</p> <pre><code>#include &lt;windows.h&gt; // for windows touch #include "RawTouchData.h" //library class that I created #include &lt;string.h&gt; #include &lt;tchar.h&gt; 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; }; </code></pre> <p>The source file:</p> <pre><code>#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 &lt; MAXPOINTS; i++){ if (ptr_bc-&gt;idLookup[i] == -1){ ptr_bc-&gt;idLookup[i] = dwID; return i; }else{ if (ptr_bc-&gt;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-&gt;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(&amp;wcex)) { MessageBox(NULL, _T("Call to RegisterClassEx failed!"), _T("Win32 Guided Tour"), NULL); return 1; } ptr_bc-&gt;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&lt; MAXPOINTS; i++){ ptr_bc-&gt;points[i][0] = -1; ptr_bc-&gt;points[i][1] = -1; ptr_bc-&gt;idLookup[i] = -1; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); // Main message loop: MSG msg; while (GetMessage(&amp;msg, NULL, 0, 0)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;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-&gt;cInputs = LOWORD(wParam); pptr_bc-&gt;pInputs = new rtd::TOUCHINPUT[ pptr_bc-&gt;cInputs ]; if(pptr_bc-&gt;pInputs) { if( rtd::GetTouchInputInfo((rtd::HTOUCHINPUT)lParam, pptr_bc-&gt;cInputs, pptr_bc-&gt;pInputs, sizeof(rtd::TOUCHINPUT)) ) { for (int i=0; i &lt; static_cast&lt;INT&gt;(pptr_bc-&gt;cInputs); i++) { rtd::TOUCHINPUT ti = pptr_bc-&gt;pInputs[i]; pptr_bc-&gt;index = pptr_bc-&gt;GetContactIndex(ti.dwID); if(ti.dwID != 0 &amp;&amp; pptr_bc-&gt;index &lt; MAXPOINTS ) { //get screen corrdinates of touch pptr_bc-&gt;ptInput.x = TOUCH_COORD_TO_PIXEL(ti.x); pptr_bc-&gt;ptInput.y = TOUCH_COORD_TO_PIXEL(ti.y); //get coordinates relative to the top left of the application window ScreenToClient(hWnd, &amp;pptr_bc-&gt;ptInput); if(ti.dwFlags &amp; TOUCHEVENTF_UP) { pptr_bc-&gt;points[pptr_bc-&gt;index][0] = -1; pptr_bc-&gt;points[pptr_bc-&gt;index][1] = -1; } else { pptr_bc-&gt;points[pptr_bc-&gt;index][0] = pptr_bc-&gt;ptInput.x; pptr_bc-&gt;points[pptr_bc-&gt;index][1] = pptr_bc-&gt;ptInput.y; } } } } rtd::CloseTouchInputHandle((rtd::HTOUCHINPUT)lParam); delete [] pptr_bc-&gt;pInputs; } InvalidateRect(hWnd, NULL, FALSE); break; case WM_PAINT: hdc = BeginPaint(hWnd, &amp;ps); RECT client; GetClientRect(hWnd, &amp;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, &amp;client, whiteBrush); //Draw Touched Points for (pptr_bc-&gt;i=0; pptr_bc-&gt;i &lt; MAXPOINTS; pptr_bc-&gt;i++) { toucPointBrushes = CreateSolidBrush(pptr_bc-&gt;colors[pptr_bc-&gt;i]); SelectObject( memDC, toucPointBrushes); pptr_bc-&gt;x = pptr_bc-&gt;points[pptr_bc-&gt;i][0]; pptr_bc-&gt;y = pptr_bc-&gt;points[pptr_bc-&gt;i][1]; if (pptr_bc-&gt;x &gt;0 &amp;&amp; pptr_bc-&gt;y&gt;0) { Ellipse(memDC, pptr_bc-&gt;x - pptr_bc-&gt;radius, pptr_bc-&gt;y - pptr_bc-&gt;radius, pptr_bc-&gt;x + pptr_bc-&gt;radius, pptr_bc-&gt;y + pptr_bc-&gt;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, &amp;ps); DeleteObject(hMemBmp); // prevents memory leak break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } </code></pre> <p>Here is the RawTouchData file:</p> <pre><code>#ifndef RAWTOUCHDATA_H #define RAWTOUCHDATA_H #pragma once //#define __in __allowed(on_parameter) #if (defined(_M_IX86) || defined(_M_IA64) || defined(_M_AMD64)) &amp;&amp; !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) &amp;&amp; (defined(_X86_) || defined(_M_IX86)) &amp;&amp; _MSC_VER &gt;= 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 &lt; __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)) &amp;&amp; ((_MSC_VER &gt;= 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 &gt;= 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 &gt;= 0x0601) #define WM_TOUCH 0x0240 #endif /* WINVER &gt;= 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 &gt;= 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 &gt;= 0x0601 */ #ifdef __cplusplus } #endif /* __cplusplus */ } #endif //RAWTOUCHDATA_H </code></pre> <p>If anyone can catch what I missed I would be most appreciative. Thank you in advanced!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload