Working touch support.

This commit is contained in:
Quantum 2016-02-14 16:26:49 -05:00
parent 0f297cfae3
commit c8a835e83f
3 changed files with 211 additions and 61 deletions

View file

@ -3,7 +3,7 @@ INCDIR=include
CXX=cl /nologo CXX=cl /nologo
LD=link /nologo LD=link /nologo
CXXFLAGS=/c /O1 /I$(INCDIR) /W4 /Zi /DWIN32_LEAN_AND_MEAN /DWINVER=0x0501 /D_WIN32_WINNT=0x0501 /DUNICODE /D_UNICODE CXXFLAGS=/c /O1 /I$(INCDIR) /W4 /Zi /DWIN32_LEAN_AND_MEAN /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DUNICODE /D_UNICODE
LDFLAGS=/subsystem:windows /debug /incremental:no /opt:REF LDFLAGS=/subsystem:windows /debug /incremental:no /opt:REF
RC=rc /nologo RC=rc /nologo
RCFLAGS=/i$(INCDIR) RCFLAGS=/i$(INCDIR)

View file

@ -8,6 +8,10 @@
#include <commctrl.h> #include <commctrl.h>
#include <shellapi.h> #include <shellapi.h>
typedef BOOL (WINAPI *T_GetTouchInputInfo)(HTOUCHINPUT hTouchInput, UINT cInputs, PTOUCHINPUT pInputs, int cbSize);
typedef BOOL (WINAPI *T_CloseTouchInputHandle)(HTOUCHINPUT hTouchInput);
typedef BOOL (WINAPI *T_RegisterTouchWindow)(HWND hWnd, ULONG ulFlags);
#define MPCM_GETKEYSTATUS (WM_USER + 0) #define MPCM_GETKEYSTATUS (WM_USER + 0)
#define MPCM_SETKEYSTATUS (WM_USER + 1) #define MPCM_SETKEYSTATUS (WM_USER + 1)
#define MPCM_GETOCTAVES (WM_USER + 2) #define MPCM_GETOCTAVES (WM_USER + 2)
@ -19,6 +23,15 @@
#define MMWM_TURNNOTE (WM_APP + 0) #define MMWM_TURNNOTE (WM_APP + 0)
#define MMWM_NOTEID (WM_APP + 1) #define MMWM_NOTEID (WM_APP + 1)
#define MAXPOINTS 20
typedef struct {
bool down;
POINTL point;
int lastNote;
int lastKey;
} PianoTouchPoint;
class PianoControl : public Window { class PianoControl : public Window {
public: public:
virtual LPCTSTR ClassName() { return TEXT("KeyboardControl"); } virtual LPCTSTR ClassName() { return TEXT("KeyboardControl"); }
@ -26,13 +39,13 @@ public:
DWORD dwStyle = 0, DWORD dwStyle = 0,
int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT,
int cx = CW_USEDEFAULT, int cy = CW_USEDEFAULT); int cx = CW_USEDEFAULT, int cy = CW_USEDEFAULT);
virtual void SetOctaves(int octaves); virtual void SetOctaves(int octaves);
virtual int GetOctaves() { return octaves; } virtual int GetOctaves() { return octaves; }
virtual void SetKeyStatus(int key, bool down); virtual void SetKeyStatus(int key, bool down);
virtual bool GetKeyStatus(int key); virtual bool GetKeyStatus(int key);
virtual void SetKeyText(int key, LPCWSTR text); virtual void SetKeyText(int key, LPCWSTR text);
virtual LPCWSTR GetKeyText(int key); virtual LPCWSTR GetKeyText(int key);
@ -41,7 +54,7 @@ public:
virtual void SetBackground(HBRUSH background) { hBackground = background; } virtual void SetBackground(HBRUSH background) { hBackground = background; }
virtual HBRUSH GetBackground() { return hBackground; } virtual HBRUSH GetBackground() { return hBackground; }
HFONT GetFont() { return hFont; } HFONT GetFont() { return hFont; }
void SetFont(HFONT font) { hFont = font; } void SetFont(HFONT font) { hFont = font; }
protected: protected:
@ -51,7 +64,15 @@ protected:
void OnPaint(); void OnPaint();
virtual void PaintContent(PAINTSTRUCT *pps); virtual void PaintContent(PAINTSTRUCT *pps);
BOOL WinRegisterClass(WNDCLASS *pwc); BOOL WinRegisterClass(WNDCLASS *pwc);
void OnTouchPoint(UINT id, int x, int y);
int GetTouchPointID(DWORD dwID);
PianoTouchPoint touchPoint[MAXPOINTS];
DWORD touchPointID[MAXPOINTS];
bool hasTouch;
T_GetTouchInputInfo F_GetTouchInputInfo;
T_CloseTouchInputHandle F_CloseTouchInputHandle;
virtual int keyIDToInternal(int id, bool &black); virtual int keyIDToInternal(int id, bool &black);
virtual int internalToKeyID(int id, bool black); virtual int internalToKeyID(int id, bool black);
virtual bool haveBlackToLeft(int id); virtual bool haveBlackToLeft(int id);
@ -61,21 +82,21 @@ protected:
} }
virtual void UpdateKey(int key, bool black); virtual void UpdateKey(int key, bool black);
virtual int hitTest(int x, int y, bool &black); virtual int hitTest(int x, int y, bool &black);
bool *blackStatus; bool *blackStatus;
bool *whiteStatus; bool *whiteStatus;
LPCWSTR *blackText; LPCWSTR *blackText;
LPCWSTR *whiteText; LPCWSTR *whiteText;
int octaves; int octaves;
HFONT hFont; HFONT hFont;
HWND hwParent; HWND hwParent;
HDC hMemDC; HDC hMemDC;
HBITMAP hMemBitmap; HBITMAP hMemBitmap;
HBRUSH hBackground; HBRUSH hBackground;
int bmx, bmy; int bmx, bmy;
bool mouseDown; bool mouseDown;
int lastNote, lastKey; int lastNote, lastKey;
}; };

View file

@ -4,11 +4,16 @@
#include <windowsx.h> #include <windowsx.h>
#include <stdio.h> #include <stdio.h>
#include <tchar.h>
#include <tpcshrd.h>
#ifndef max #ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b)) #define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b)) #define min(a, b) (((a) < (b)) ? (a) : (b))
#endif #endif
#define MOUSEEVENTF_FROMTOUCH 0xFF515700
BOOL PianoControl::WinRegisterClass(WNDCLASS *pwc) BOOL PianoControl::WinRegisterClass(WNDCLASS *pwc)
{ {
return Window::WinRegisterClass(pwc); return Window::WinRegisterClass(pwc);
@ -24,16 +29,48 @@ LRESULT PianoControl::OnCreate()
hFont = CreateFontIndirect(&ncmMetrics.lfMessageFont); hFont = CreateFontIndirect(&ncmMetrics.lfMessageFont);
hwParent = GetParent(m_hwnd); hwParent = GetParent(m_hwnd);
hMemDC = NULL; hMemDC = NULL;
hMemBitmap = NULL; hMemBitmap = NULL;
bmx = bmy = 0; bmx = bmy = 0;
blackStatus = whiteStatus = NULL; blackStatus = whiteStatus = NULL;
blackText = whiteText = NULL; blackText = whiteText = NULL;
mouseDown = false; mouseDown = false;
lastNote = lastKey = 0; lastNote = lastKey = 0;
int touchSupport = GetSystemMetrics(SM_DIGITIZER);
T_RegisterTouchWindow F_RegisterTouchWindow = NULL;
hasTouch = false;
if (touchSupport & NID_READY) {
// Has touch
hasTouch = true;
F_GetTouchInputInfo = (T_GetTouchInputInfo) GetProcAddress(GetModuleHandle(TEXT("user32")), "GetTouchInputInfo");
F_CloseTouchInputHandle = (T_CloseTouchInputHandle) GetProcAddress(GetModuleHandle(TEXT("user32")), "CloseTouchInputHandle");
F_RegisterTouchWindow = (T_RegisterTouchWindow) GetProcAddress(GetModuleHandle(TEXT("user32")), "RegisterTouchWindow");
if (!F_GetTouchInputInfo || !F_CloseTouchInputHandle || !F_RegisterTouchWindow)
hasTouch = false;
}
if (hasTouch) {
F_RegisterTouchWindow(m_hwnd, TWF_WANTPALM);
memset(touchPoint, 0, MAXPOINTS * sizeof(PianoTouchPoint));
ATOM atom = GlobalAddAtom(MICROSOFT_TABLETPENSERVICE_PROPERTY);
SetProp(m_hwnd, MICROSOFT_TABLETPENSERVICE_PROPERTY, (HANDLE) (
TABLET_DISABLE_PRESSANDHOLD | // disables press and hold (right-click) gesture
TABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up (waves)
TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen button down
TABLET_DISABLE_FLICKS // disables pen flicks (back, forward, drag down, drag up)
));
GlobalDeleteAtom(atom);
}
for (int i = 0; i < MAXPOINTS; ++i)
touchPointID[i] = (DWORD) -1;
SetOctaves(2); SetOctaves(2);
return 0; return 0;
} }
@ -49,7 +86,7 @@ void PianoControl::SetOctaves(int octaves)
{ {
bool *newBlackStatus, *newWhiteStatus; bool *newBlackStatus, *newWhiteStatus;
LPCWSTR *newBlackText, *newWhiteText; LPCWSTR *newBlackText, *newWhiteText;
#define RENEW(type, newname, store) {\ #define RENEW(type, newname, store) {\
newname = new type[7 * octaves];\ newname = new type[7 * octaves];\
if (store) {\ if (store) {\
@ -63,7 +100,7 @@ void PianoControl::SetOctaves(int octaves)
RENEW(bool, newWhiteStatus, whiteStatus); RENEW(bool, newWhiteStatus, whiteStatus);
RENEW(LPCWSTR, newBlackText, blackText); RENEW(LPCWSTR, newBlackText, blackText);
RENEW(LPCWSTR, newWhiteText, whiteText); RENEW(LPCWSTR, newWhiteText, whiteText);
this->octaves = octaves; this->octaves = octaves;
} }
@ -80,7 +117,7 @@ void PianoControl::UpdateKey(int key, bool black)
bwidth = width / 12 / octaves; // smaller bwidth = width / 12 / octaves; // smaller
bheight = height / 2; bheight = height / 2;
hbwidth = bwidth / 2; hbwidth = bwidth / 2;
if (black) { if (black) {
client.left += (key * wwidth) - hbwidth + 2; client.left += (key * wwidth) - hbwidth + 2;
client.right = client.left + bwidth - 5; client.right = client.left + bwidth - 5;
@ -98,7 +135,7 @@ void PianoControl::SetKeyStatus(int key, bool down)
{ {
bool black; bool black;
int id = keyIDToInternal(key, black); int id = keyIDToInternal(key, black);
(black ? blackStatus : whiteStatus)[id] = down; (black ? blackStatus : whiteStatus)[id] = down;
UpdateKey(id, black); UpdateKey(id, black);
} }
@ -107,7 +144,7 @@ bool PianoControl::GetKeyStatus(int key)
{ {
bool black; bool black;
int id = keyIDToInternal(key, black); int id = keyIDToInternal(key, black);
return (black ? blackStatus : whiteStatus)[id]; return (black ? blackStatus : whiteStatus)[id];
} }
@ -115,7 +152,7 @@ void PianoControl::SetKeyText(int key, LPCWSTR text)
{ {
bool black; bool black;
int id = keyIDToInternal(key, black); int id = keyIDToInternal(key, black);
(black ? blackText : whiteText)[id] = text; (black ? blackText : whiteText)[id] = text;
UpdateKey(id, black); UpdateKey(id, black);
} }
@ -124,7 +161,7 @@ LPCWSTR PianoControl::GetKeyText(int key)
{ {
bool black; bool black;
int id = keyIDToInternal(key, black); int id = keyIDToInternal(key, black);
return (black ? blackText : whiteText)[id]; return (black ? blackText : whiteText)[id];
} }
@ -140,7 +177,7 @@ int PianoControl::keyIDToInternal(int id, bool &black) {
default: default:
black = false; black = false;
} }
int ret = 0; int ret = 0;
switch (id % 12) { switch (id % 12) {
case 0: case 0:
@ -170,7 +207,7 @@ int PianoControl::keyIDToInternal(int id, bool &black) {
ret = 6; ret = 6;
break; break;
} }
return id / 12 * 7 + ret; return id / 12 * 7 + ret;
} }
@ -224,7 +261,7 @@ int PianoControl::hitTest(int x, int y, bool &black)
RECT client; RECT client;
int width, height; int width, height;
int wwidth, bwidth, bheight, hbwidth; int wwidth, bwidth, bheight, hbwidth;
GetClientRect(m_hwnd, &client); GetClientRect(m_hwnd, &client);
width = client.right - client.left; width = client.right - client.left;
height = client.bottom - client.top; height = client.bottom - client.top;
@ -233,10 +270,10 @@ int PianoControl::hitTest(int x, int y, bool &black)
bheight = height / 2; bheight = height / 2;
bheight = height / 2; bheight = height / 2;
hbwidth = bwidth / 2; hbwidth = bwidth / 2;
int key = x / wwidth; int key = x / wwidth;
int dx = x % wwidth; int dx = x % wwidth;
if (y < bheight && (dx < hbwidth || dx > (wwidth - hbwidth))) { if (y < bheight && (dx < hbwidth || dx > (wwidth - hbwidth))) {
int temp = key; int temp = key;
if (dx >= hbwidth) if (dx >= hbwidth)
@ -251,7 +288,7 @@ int PianoControl::hitTest(int x, int y, bool &black)
return temp; return temp;
} }
} }
black = false; black = false;
return key; return key;
} }
@ -280,10 +317,10 @@ void PianoControl::PaintContent(PAINTSTRUCT *pps)
bheight = height / 2; bheight = height / 2;
bheight = height / 2; bheight = height / 2;
hbwidth = bwidth / 2; hbwidth = bwidth / 2;
hbOriginal = SelectBrush(hdc, hBackground); hbOriginal = SelectBrush(hdc, hBackground);
hPenOriginal = SelectPen(hdc, hPenDC); hPenOriginal = SelectPen(hdc, hPenDC);
GetObject(hFont, sizeof(LOGFONT), &lf); GetObject(hFont, sizeof(LOGFONT), &lf);
lf.lfWidth = 0; lf.lfWidth = 0;
lf.lfHeight = min(bwidth, bheight / 4); lf.lfHeight = min(bwidth, bheight / 4);
@ -333,18 +370,18 @@ void PianoControl::PaintContent(PAINTSTRUCT *pps)
#define GETBORDER0(down) (down ? GetSysColor(COLOR_3DLIGHT) : RGB(0, 0, 0)) #define GETBORDER0(down) (down ? GetSysColor(COLOR_3DLIGHT) : RGB(0, 0, 0))
#define GETBORDER1(down) (down ? GetSysColor(COLOR_3DSHADOW) : GetSysColor(COLOR_3DDKSHADOW)) #define GETBORDER1(down) (down ? GetSysColor(COLOR_3DSHADOW) : GetSysColor(COLOR_3DDKSHADOW))
#define GETBORDER2(down) (down ? GetSysColor(COLOR_3DDKSHADOW) : GetSysColor(COLOR_3DSHADOW)) #define GETBORDER2(down) (down ? GetSysColor(COLOR_3DDKSHADOW) : GetSysColor(COLOR_3DSHADOW))
rect.top = height - CURVE_SIZE, rect.bottom = height; rect.top = height - CURVE_SIZE, rect.bottom = height;
rect.left = client.left, rect.right = client.right; rect.left = client.left, rect.right = client.right;
FillRect(hdc, &rect, hBackground); FillRect(hdc, &rect, hBackground);
rect.top = client.top, rect.bottom = client.bottom; rect.top = client.top, rect.bottom = client.bottom;
rect.left = client.right - width % (7 * octaves), rect.right = client.right; rect.left = client.right - width % (7 * octaves), rect.right = client.right;
FillRect(hdc, &rect, hBackground); FillRect(hdc, &rect, hBackground);
for (int i = 0; i < 7 * octaves; ++i) { for (int i = 0; i < 7 * octaves; ++i) {
int sx = i * wwidth, ex = i * wwidth + wwidth - 1; int sx = i * wwidth, ex = i * wwidth + wwidth - 1;
bool down = whiteStatus[i]; bool down = whiteStatus[i];
SelectBrush(hdc, hbDC); SelectBrush(hdc, hbDC);
SetDCBrushColor(hdc, GETBORDER1(down)); SetDCBrushColor(hdc, GETBORDER1(down));
DRAWBOX(bheight, 0, height, GETBORDER0(down)); DRAWBOX(bheight, 0, height, GETBORDER0(down));
@ -352,10 +389,10 @@ void PianoControl::PaintContent(PAINTSTRUCT *pps)
DRAWBOX(bheight, 1, height, GETBORDER1(down)); DRAWBOX(bheight, 1, height, GETBORDER1(down));
SelectBrush(hdc, hbFace); SelectBrush(hdc, hbFace);
DRAWBOX(bheight, 2, height, GETBORDER2(down)); DRAWBOX(bheight, 2, height, GETBORDER2(down));
rect.top = 0, rect.bottom = bheight, rect.left = sx, rect.right = ex; rect.top = 0, rect.bottom = bheight, rect.left = sx, rect.right = ex;
FillRect(hdc, &rect, hBackground); FillRect(hdc, &rect, hBackground);
switch (haveBlack(i)) { switch (haveBlack(i)) {
case 0: // none case 0: // none
DRAWBORDER(bheight, 0, GETBORDER0(down)); DRAWBORDER(bheight, 0, GETBORDER0(down));
@ -405,7 +442,7 @@ void PianoControl::PaintContent(PAINTSTRUCT *pps)
FillRect(hdc, &rect, hbFace); FillRect(hdc, &rect, hbFace);
break; break;
} }
if (whiteText[i]) { if (whiteText[i]) {
INITIALIZE_PAINT_TEXT(whiteText); INITIALIZE_PAINT_TEXT(whiteText);
rect.top = bheight + bheight / 7, rect.bottom = height - bheight / 7; rect.top = bheight + bheight / 7, rect.bottom = height - bheight / 7;
@ -413,7 +450,7 @@ void PianoControl::PaintContent(PAINTSTRUCT *pps)
SetTextColor(hdc, RGB(0, 0, 0)); SetTextColor(hdc, RGB(0, 0, 0));
DrawText(hdc, szBuffer, -1, &rect, DT_CENTER); DrawText(hdc, szBuffer, -1, &rect, DT_CENTER);
} }
rect.top = client.top, rect.bottom = client.bottom; rect.top = client.top, rect.bottom = client.bottom;
rect.left = ex, rect.right = ex + 1; rect.left = ex, rect.right = ex + 1;
FillRect(hdc, &rect, hBackground); FillRect(hdc, &rect, hBackground);
@ -431,7 +468,7 @@ void PianoControl::PaintContent(PAINTSTRUCT *pps)
SetDCBrushColor(hdc, colour); SetDCBrushColor(hdc, colour);
DRAWBOX(-CURVE_SIZE, j, bheight - 2, colour); DRAWBOX(-CURVE_SIZE, j, bheight - 2, colour);
} }
if (blackText[i]) { if (blackText[i]) {
INITIALIZE_PAINT_TEXT(blackText); INITIALIZE_PAINT_TEXT(blackText);
rect.top = bheight / 7, rect.bottom = bheight - bheight / 7; rect.top = bheight / 7, rect.bottom = bheight - bheight / 7;
@ -462,13 +499,13 @@ void PianoControl::OnPaint()
{ {
PAINTSTRUCT ps; PAINTSTRUCT ps;
BeginPaint(m_hwnd, &ps); BeginPaint(m_hwnd, &ps);
int x = ps.rcPaint.left; int x = ps.rcPaint.left;
int y = ps.rcPaint.top; int y = ps.rcPaint.top;
int cx = ps.rcPaint.right - ps.rcPaint.left; int cx = ps.rcPaint.right - ps.rcPaint.left;
int cy = ps.rcPaint.bottom - ps.rcPaint.top; int cy = ps.rcPaint.bottom - ps.rcPaint.top;
HDC hdc = ps.hdc; HDC hdc = ps.hdc;
if (!hMemDC) if (!hMemDC)
hMemDC = CreateCompatibleDC(hdc); hMemDC = CreateCompatibleDC(hdc);
if (!hMemBitmap || cx > bmx || cy > bmy) { if (!hMemBitmap || cx > bmx || cy > bmy) {
@ -481,7 +518,7 @@ void PianoControl::OnPaint()
} }
if (hMemDC && hMemBitmap) { if (hMemDC && hMemBitmap) {
ps.hdc = hMemDC; ps.hdc = hMemDC;
HBITMAP hbmPrev = SelectBitmap(hMemDC, hMemBitmap); HBITMAP hbmPrev = SelectBitmap(hMemDC, hMemBitmap);
SetWindowOrgEx(hMemDC, x, y, NULL); SetWindowOrgEx(hMemDC, x, y, NULL);
@ -495,15 +532,72 @@ void PianoControl::OnPaint()
EndPaint(m_hwnd, &ps); EndPaint(m_hwnd, &ps);
} }
void PianoControl::DisableDraw() { void PianoControl::DisableDraw()
{
SendMessage(m_hwnd, WM_SETREDRAW, FALSE, 0); SendMessage(m_hwnd, WM_SETREDRAW, FALSE, 0);
} }
void PianoControl::EnableDraw() { void PianoControl::EnableDraw()
{
SendMessage(m_hwnd, WM_SETREDRAW, TRUE, 0); SendMessage(m_hwnd, WM_SETREDRAW, TRUE, 0);
RedrawWindow(m_hwnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE); RedrawWindow(m_hwnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
} }
void PianoControl::OnTouchPoint(UINT id, int x, int y)
{
if (x != -1 && y != -1) {
// Touch point is down
if (touchPoint[id].down) {
// Dragged
bool black;
int internal = hitTest(x, y, black);
int key = internalToKeyID(internal, black);
int external = SendMessage(hwParent, MMWM_NOTEID, key, 0);
if (touchPoint[id].lastNote != external) {
SendMessage(hwParent, MMWM_TURNNOTE, touchPoint[id].lastNote, 0);
SetKeyStatus(touchPoint[id].lastKey, false);
SendMessage(hwParent, MMWM_TURNNOTE, external, 1);
SetKeyStatus(key, true);
touchPoint[id].lastNote = external;
touchPoint[id].lastKey = key;
}
} else {
// Pressed
bool black;
int internal = hitTest(x, y, black);
int key = internalToKeyID(internal, black);
int external = SendMessage(hwParent, MMWM_NOTEID, key, 0);
SendMessage(hwParent, MMWM_TURNNOTE, external, 1);
SetKeyStatus(key, true);
touchPoint[id].lastNote = external;
touchPoint[id].lastKey = key;
touchPoint[id].down = true;
}
touchPoint[id].point.x = x;
touchPoint[id].point.y = y;
} else {
// It just went up
SendMessage(hwParent, MMWM_TURNNOTE, touchPoint[id].lastNote, 0);
SetKeyStatus(touchPoint[id].lastKey, false);
touchPoint[id].down = false;
}
}
int PianoControl::GetTouchPointID(DWORD dwID)
{
for (DWORD i = 0; i < MAXPOINTS; ++i) {
if (touchPointID[i] == dwID)
return i;
}
for (DWORD i = 0; i < MAXPOINTS; ++i) {
if (touchPointID[i] == (DWORD) -1) {
touchPointID[i] = dwID;
return i;
}
}
return -1;
}
LRESULT PianoControl::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) LRESULT PianoControl::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
switch (uMsg) { switch (uMsg) {
@ -520,27 +614,29 @@ LRESULT PianoControl::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_SIZE: case WM_SIZE:
InvalidateRect(m_hwnd, NULL, TRUE); InvalidateRect(m_hwnd, NULL, TRUE);
return 0; return 0;
case WM_LBUTTONDOWN: { case WM_LBUTTONDOWN:
bool black; if ((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) != MOUSEEVENTF_FROMTOUCH) {
int internal = hitTest(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), black); bool black;
int key = internalToKeyID(internal, black); int internal = hitTest(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), black);
int external = SendMessage(hwParent, MMWM_NOTEID, key, 0); int key = internalToKeyID(internal, black);
SendMessage(hwParent, MMWM_TURNNOTE, external, 1); int external = SendMessage(hwParent, MMWM_NOTEID, key, 0);
SetKeyStatus(key, true); SendMessage(hwParent, MMWM_TURNNOTE, external, 1);
lastNote = external; SetKeyStatus(key, true);
lastKey = key; lastNote = external;
mouseDown = true; lastKey = key;
SetFocus(m_hwnd); mouseDown = true;
return 0; SetFocus(m_hwnd);
} return 0;
case WM_LBUTTONUP: { }
SendMessage(hwParent, MMWM_TURNNOTE, lastNote, 0); case WM_LBUTTONUP:
SetKeyStatus(lastKey, false); if ((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) != MOUSEEVENTF_FROMTOUCH) {
mouseDown = false; SendMessage(hwParent, MMWM_TURNNOTE, lastNote, 0);
return 0; SetKeyStatus(lastKey, false);
} mouseDown = false;
return 0;
}
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
if (mouseDown) { if ((GetMessageExtraInfo() & 0x82) != 0x82 && mouseDown) {
bool black; bool black;
int internal = hitTest(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), black); int internal = hitTest(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), black);
int key = internalToKeyID(internal, black); int key = internalToKeyID(internal, black);
@ -564,6 +660,39 @@ LRESULT PianoControl::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_SYSCHAR: case WM_SYSCHAR:
case WM_SYSDEADCHAR: case WM_SYSDEADCHAR:
return SendMessage(hwParent, uMsg, wParam, lParam); return SendMessage(hwParent, uMsg, wParam, lParam);
case WM_TOUCH: {
if (!hasTouch)
break;
UINT cInputs = LOWORD(wParam);
TOUCHINPUT *pInputs = new TOUCHINPUT[cInputs];
if (pInputs != NULL) {
if (F_GetTouchInputInfo((HTOUCHINPUT) lParam, cInputs, pInputs, sizeof(TOUCHINPUT))) {
for (UINT i = 0; i < cInputs; ++i) {
POINT ptInput;
int id = GetTouchPointID(pInputs[i].dwID);
if (id == -1)
continue; // presumably you had 20 touch points
ptInput.x = TOUCH_COORD_TO_PIXEL(pInputs[i].x);
ptInput.y = TOUCH_COORD_TO_PIXEL(pInputs[i].y);
ScreenToClient(m_hwnd, &ptInput);
if (pInputs[i].dwFlags & TOUCHEVENTF_UP) {
OnTouchPoint(id, -1, -1);
touchPointID[id] = (DWORD) -1; // Free the ID
} else {
OnTouchPoint(id, ptInput.x, ptInput.y);
}
}
F_CloseTouchInputHandle((HTOUCHINPUT) lParam);
delete [] pInputs;
return 0;
}
delete [] pInputs;
}
break;
}
case WM_GETFONT: case WM_GETFONT:
return (LRESULT) GetFont(); return (LRESULT) GetFont();
case WM_SETFONT: case WM_SETFONT: