Фон меняется после того, как изображения нарисованы на экране

Мы узнаем о событиях касания Windows Raw в классе, используя Visual Studios 2012 в C ++. Моя демоверсия работает, и она делает именно то, что и должна, которая рисует круги под кончиками ваших пальцев, чтобы обнаружить, что произошло событие касания. Но по прошествии определенного времени, и если вы все еще нажимаете на экране с нарисованными кругами, экран становится синим! Круги все еще показывают, но они также синие с черными контурами, и я все еще могу перемещать их. Я показал профессору, и он не может понять это, поэтому я и пришел сюда. Может ли кто-нибудь взглянуть на мой код, чтобы сообщить мне, в чем причина?

// GT_HelloWorldWin32.cpp
// compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c
#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

#include <windows.h> // for windows touch
#include <windowsx.h> // included for point conversion
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#include "wtypes.h"#include <iostream>

using namespace std;

// The main window class name.
TCHAR szWindowClass[] = _T("win32app");

// The string that appears in the application's title bar.
TCHAR szTitle[] = _T("Hello World!");

//Instancing the handler
HINSTANCE hInst;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

//Maximum ammount of touches allowed
#define MAXPOINTS 10

// 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
static int radius = 30;

// There should be at least as many colors
// as there can be touch points so that you
// can have different colors for each point
COLORREF colors[] = { RGB(153,255,51),
RGB(153,0,0),
RGB(0,153,0),
RGB(255,255,0),
RGB(255,51,204),
RGB(0,0,0),
RGB(0,153,0),
RGB(153, 255, 255),
RGB(153,153,255),
RGB(0,51,153)
};

int wmId, wmEvent, i, x, y, index;

UINT cInputs;
PTOUCHINPUT pInputs;
POINT ptInput;

// This function is used to return an index given an ID
int GetContactIndex(int dwID){
for (int i=0; i < MAXPOINTS; i++){
if (idLookup[i] == -1){
idLookup[i] = dwID;
return i;
}else{
if (idLookup[i] == dwID){
return i;
}
}
}
// Out of contacts
return -1;
}

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

WNDCLASSEX wcex;

int width = 0, height = 0; // Screen resolution

GetScreenResolution(width, height);

wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = 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 = szWindowClass;
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;
}

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(
szWindowClass,
szTitle,
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
RegisterTouchWindow(hWnd, 0);

// the following code initializes the points
for (int i=0; i< MAXPOINTS; i++){
points[i][0] = -1;
points[i][1] = -1;
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_DESTROY - post a quit message and return
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// For double buffering
static HDC memDC = 0;
static HBITMAP hMemBmp = 0;
HBITMAP hOldBmp = 0;
//For drawing / fills
PAINTSTRUCT ps;
HDC hdc;

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
cInputs = LOWORD(wParam);
pInputs = new TOUCHINPUT[ cInputs ];
if(pInputs)
{
if( GetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT)) )
{
for (int i=0; i < static_cast<INT>(cInputs); i++)
{
TOUCHINPUT ti = pInputs[i];
index = GetContactIndex(ti.dwID);

if(ti.dwID != 0 && index < MAXPOINTS )
{
//get screen corrdinates of touch
ptInput.x = TOUCH_COORD_TO_PIXEL(ti.x);
ptInput.y = TOUCH_COORD_TO_PIXEL(ti.y);

//get coordinates relative to the top left of the application window
ScreenToClient(hWnd, &ptInput);

if(ti.dwFlags & TOUCHEVENTF_UP)
{
points[index][0] = -1;
points[index][1] = -1;
}
else
{
points[index][0] = ptInput.x;
points[index][1] = ptInput.y;
}
}
}
}
CloseTouchInputHandle((HTOUCHINPUT)lParam);
delete [] 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);

FillRect(memDC, &client, CreateSolidBrush(RGB(255,255,255)));

//Draw Touched Points
for (i=0; i < MAXPOINTS; i++)
{
SelectObject( memDC, CreateSolidBrush(colors[i]));
x = points[i][0];
y = points[i][1];

if (x >0 && y>0)
{
Ellipse(memDC, x - radius, y - radius, x + radius, y + radius);
}
}
BitBlt(hdc, 0,0, client.right, client.bottom, memDC, 0,0, SRCCOPY);
EndPaint(hWnd, &ps);
ReleaseDC(hWnd, hdc);
//DeleteObject(hMemBmp);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

1

Решение

Теперь я вижу проблему. У вас есть утечка ресурсов GDI.

В двух местах вы звоните CreateSolidBrush но вы никогда не удаляете созданные вами кисти. Вы делаете это здесь

FillRect(memDC, &client, CreateSolidBrush(RGB(255,255,255)));

и здесь

SelectObject( memDC, CreateSolidBrush(colors[i]));

Действительно, вы должны назначить результат каждогоCreateSolidBrush функция к HBRUSH а затем позвоните DeleteObject на это, когда вы закончили с этим.

Вам также нужно выпустить свой растровое изображение: DeleteObject(hMemBmp) который вы закомментировали, а также удалить вызов ReleaseDC как я сказал в комментариях.

Как правило, вы должны внимательно следить за всеми объектами GDI, которые вы создали, и не забудьте удалить их, когда закончите с ними.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]