3 /////////////////////////////////////////////////////////////////////////////
5 // Copyright (c) 2002 Iain Murray, Inference Group, Cavendish, Cambridge.
7 /////////////////////////////////////////////////////////////////////////////
9 #include "..\Common\WinCommon.h"
13 #include "../Dasher.h"
14 #include "../DasherInterface.h"
18 #define PRESSED 0x8000
19 #define REPEAT 0x40000000
20 using namespace Dasher
;
22 #include "../TabletPC/SystemInfo.h"
25 /////////////////////////////////////////////////////////////////////////////
27 CCanvas::CCanvas(CDasherInterface
*DI
, Dasher::CEventHandler
*pEventHandler
, CSettingsStore
*pSettingsStore
)
28 :m_pDasherInterface(DI
), imousex(0), imousey(0), buttonnum(0), mousepostime(0) ,
29 m_dwTicksLastEvent(0), m_bButtonDown(false), m_pScreen(0),
30 CDasherComponent(pEventHandler
, pSettingsStore
)
38 GetClassInfo(NULL
, TEXT("STATIC"), &canvasclass
);
39 canvasclass
.lpszClassName
= TEXT("CANVAS");
44 /////////////////////////////////////////////////////////////////////////////
46 HWND
CCanvas::Create(HWND hParent
)
48 HWND hWnd
= CWindowImpl
<CCanvas
>::Create(hParent
, NULL
, NULL
, WS_CHILD
| WS_VISIBLE
,WS_EX_CLIENTEDGE
);
54 // Create input device objects
55 // NB We create the SocketInput object now, even if socket input is not enabled, because
56 // we can't safely create it later in response to a parameter change event (because it itself
57 // needs to register an event listener when it constructs itself).
59 // CreateSettingsStore only creates a new one if there isn't one there already
64 // m_pSocketInput = (CSocketInput *)m_pDasherInterface->GetModule(1);
65 // m_pSocketInput->Ref();
67 //m_pMouseInput = (CDasherMouseInput *)m_pDasherInterface->GetModule(0);
68 // m_pMouseInput->Ref();
70 /*if(m_pDasherInterface->GetBoolParameter(BP_SOCKET_INPUT_ENABLE))
72 m_pSocketInput->StartListening();
73 m_pDasherInterface->SetInput(1);
76 m_pDasherInterface->SetInput(0);
80 m_pKeyboardHelper
= new CKeyboardHelper
;
82 m_pScreen
= new CScreen(m_hdc
, 300, 300);
83 m_pScreen
->SetFont(m_pDasherInterface
->GetStringParameter(SP_DASHER_FONT
));
84 //ReleaseDC(m_hwnd,m_hDC);
85 m_pDasherInterface
->ChangeScreen(m_pScreen
);
87 for(int i
= 0; i
< 18; i
++)
92 previoustime
= GetTickCount();
98 /////////////////////////////////////////////////////////////////////////////
100 void CCanvas::SetScreenInterface(CDasherInterface
* dasherinterface
)
102 m_pScreen
->SetInterface(dasherinterface
);
105 /////////////////////////////////////////////////////////////////////////////
107 LRESULT
CCanvas::OnCreate(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
111 // If we're a tablet, initialize the event-generator
114 HRESULT h
= m_CursorInRange
.Initialize(m_hWnd
);
117 // detected tablet, but cant initialize the event-generator
124 /////////////////////////////////////////////////////////////////////////////
126 LRESULT
CCanvas::OnDestroy(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
128 int iRC
= ReleaseDC(m_hdc
);
131 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS
, NULL
, GetLastError(), MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), // Default language
132 (LPTSTR
) & lpMsgBuf
, 0, NULL
);
133 // Process any inserts in lpMsgBuf.
135 // Display the string.
136 ::MessageBox(NULL
, (LPCTSTR
) lpMsgBuf
, TEXT("Error"), MB_OK
| MB_ICONINFORMATION
);
145 /////////////////////////////////////////////////////////////////////////////
147 CCanvas::~CCanvas() {
149 //if(m_pMouseInput != NULL) {
150 // delete m_pMouseInput;
152 //if(m_pSocketInput != NULL) {
153 // delete m_pSocketInput;
156 if(m_pKeyboardHelper
)
157 delete m_pKeyboardHelper
;
160 void CCanvas::Move(int x
, int y
, int Width
, int Height
)
162 MoveWindow(x
, y
, Width
, Height
, TRUE
);
165 void CCanvas::Paint()
167 InvalidateRect(NULL
, FALSE
);
172 LRESULT
CCanvas::OnCommand(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
175 SendMessage(GetParent(), message
, wParam
, lParam
);
179 LRESULT
CCanvas::OnSetFocus(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
182 SendMessage(GetParent(), WM_DASHER_FOCUS
, 0, (LPARAM
)&m_hWnd
);
186 LRESULT
CCanvas::OnPaint(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
191 m_pScreen
->Display();
199 LRESULT
CCanvas::OnKeyUp(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
205 if(m_pKeyboardHelper
)
206 iKeyVal
= m_pKeyboardHelper
->ConvertKeyCode(wParam
);
209 m_pDasherInterface
->KeyUp(GetTickCount(), iKeyVal
);
216 if(GetKeyState(VK_CONTROL
) & PRESSED
)
217 m_pDasherInterface
->SetLongParameter(LP_BOOSTFACTOR
, 25);
219 m_pDasherInterface
->SetLongParameter(LP_BOOSTFACTOR
, 100);
222 if(GetKeyState(VK_SHIFT
) & PRESSED
)
223 m_pDasherInterface
->SetLongParameter(LP_BOOSTFACTOR
, 175);
225 m_pDasherInterface
->SetLongParameter(LP_BOOSTFACTOR
, 100);
234 LRESULT
CCanvas::OnKeyDown(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
237 TCHAR tmpAutoOffset
[128];
244 if(m_pKeyboardHelper
)
245 iKeyVal
= m_pKeyboardHelper
->ConvertKeyCode(wParam
);
248 m_pDasherInterface
->KeyDown(GetTickCount(), iKeyVal
);
253 // Space, for start/stop events etc.
255 m_pDasherInterface
->KeyDown(GetTickCount(), 0);
260 wsprintf(tmpAutoOffset
, TEXT("yAutoValue: %d"), m_pDasherInterface
->GetAutoOffset());
261 MessageBox(tmpAutoOffset
, TEXT("Auto-offset Value"), MB_OK
);
271 if(lParam
^ REPEAT
) // ignore auto-repeat
272 m_pDasherInterface
->SetLongParameter(LP_BOOSTFACTOR
, 175);
275 if(lParam
^ REPEAT
) // ignore auto-repeat
276 m_pDasherInterface
->SetLongParameter(LP_BOOSTFACTOR
, 25);
281 m_pDasherInterface
->KeyDown(GetTickCount(), 1);
284 m_pDasherInterface
->KeyDown(GetTickCount(), 2);
287 m_pDasherInterface
->KeyDown(GetTickCount(), 3);
290 m_pDasherInterface
->KeyDown(GetTickCount(), 4);
297 LRESULT
CCanvas::OnLButtonDblClk(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
300 // if( m_pDasherInterface->GetBoolParameter(BP_START_STYLUS) )
302 // m_pDasherInterface->PauseAt(0, 0);
307 LRESULT
CCanvas::OnLButtonDown(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
311 OutputDebugString(TEXT("Canvas::LButtonDown\n"));
313 // FIXME - what does this do - please document
314 LPARAM lp
= GetMessageExtraInfo();
315 if (lp
== 0xFF515702)
319 m_pDasherInterface
->KeyDown(GetTickCount(), 100);
321 // else if ( m_pDasherInterface->GetBoolParameter(BP_START_STYLUS) )
323 // // DJW - for the time being we only do stylus mode if not BP_START_MOUSE
325 // if ( m_pDasherInterface->GetBoolParameter(BP_DASHER_PAUSED) )
326 // m_pDasherInterface->Unpause(GetTickCount());
329 m_bButtonDown
= true;
333 LRESULT
CCanvas::OnLButtonUp(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
337 endturbo
= GetTickCount();
339 if(endturbo
- startturbo
> 1)
342 wsprintf(deb
, TEXT("start: %d\nend: %d\nduration: %d"), startturbo
, endturbo
, endturbo
- startturbo
);
343 OutputDebugString(deb
);
347 m_bButtonDown
= false;
353 LRESULT
CCanvas::OnCursorInRange(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
355 OutputDebugString(TEXT("CursorInRange\n"));
361 if ( m_pDasherInterface
->GetBoolParameter(BP_START_MOUSE
) )
363 if (m_pDasherInterface
->GetBoolParameter(BP_DASHER_PAUSED
))
364 m_pDasherInterface
->Unpause(GetTickCount());
371 LRESULT
CCanvas::OnCursorOutOfRange(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
373 OutputDebugString(TEXT("CursorOutOfRange\n"));
376 if ( m_pDasherInterface
->GetBoolParameter(BP_START_MOUSE
) )
378 if (!m_pDasherInterface
->GetBoolParameter(BP_DASHER_PAUSED
))
379 m_pDasherInterface
->PauseAt(0, 0);
385 LRESULT
CCanvas::OnRButtonDown(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
388 // if( m_pDasherInterface->GetBoolParameter(BP_START_STYLUS) )
390 // if( m_pDasherInterface->GetBoolParameter(BP_DASHER_PAUSED) )
391 // m_pDasherInterface->Unpause(GetTickCount());
393 // m_bButtonDown = true;
398 LRESULT
CCanvas::OnRButtonUp(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
401 m_bButtonDown
= false;
405 LRESULT
CCanvas::OnMouseMove(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
409 imousex
= LOWORD(lParam
);
410 imousey
= HIWORD(lParam
);
411 m_dwTicksLastEvent
= GetTickCount();
412 // if( m_pDasherInterface->GetBoolParameter(BP_START_STYLUS) )
414 // if( m_pDasherInterface->GetBoolParameter(BP_DASHER_PAUSED) )
415 // m_pDasherInterface->Unpause(GetTickCount());
421 LRESULT
CCanvas::OnSize(UINT message
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
429 if (LOWORD(lParam
)>0 && HIWORD(lParam
) >0)
431 m_pScreen
= new CScreen(m_hdc
, LOWORD(lParam
), HIWORD(lParam
));
432 m_pScreen
->SetFont(m_pDasherInterface
->GetStringParameter(SP_DASHER_FONT
));
433 m_pDasherInterface
->ChangeScreen(m_pScreen
);
434 InvalidateRect( NULL
, FALSE
);
439 /*LRESULT CCanvas::OnTimer(UINT message, WPARAM wParam, LPARAM lParam, BOOL& bHandled) */
441 void CCanvas::DoFrame()
444 GetCursorPos(&mousepos2
);
446 ScreenToClient(&mousepos2
);
449 GetCursorPos(&mousepos
);
451 // if(running == 0) {
452 // ScreenToClient(m_hwnd, &mousepos);
453 // if(m_pDasherInterface->GetBoolParameter(BP_MOUSEPOS_MODE) == true) // configuration option
455 // // DASHER_TRACEOUTPUT("first:%d second:%d %d\n",firstwindow,secondwindow,m_iMousePosDist);
456 // if(firstwindow != true && secondwindow != true) {
457 // m_pDasherInterface->SetLongParameter(LP_MOUSE_POS_BOX, 1);
458 // firstwindow = true;
460 // int mouseDist = m_pDasherInterface->GetLongParameter(LP_MOUSEPOSDIST);
461 // if(mousepos.y > m_pScreen->GetHeight() / 2 - mouseDist - 50 && mousepos.y < m_pScreen->GetHeight() / 2 - mouseDist + 50 && firstwindow == true) {
462 // // Mouse is in the top box
463 // if(mousepostime == 0) {
464 // mousepostime = GetTickCount();
466 // else if((GetTickCount() - mousepostime) > 2000) {
467 // firstwindow = false;
468 // secondwindow = true;
470 // m_pDasherInterface->SetLongParameter(LP_MOUSE_POS_BOX, 2);
473 // else if(firstwindow == true) {
476 // if(secondwindow == true) {
477 // if(mousepos.y < m_pScreen->GetHeight() / 2 + mouseDist + 50 && mousepos.y > (m_pScreen->GetHeight() / 2 + mouseDist - 50)) {
478 // // In second window
479 // if(mousepostime == 0) {
480 // mousepostime = GetTickCount();
482 // else if((GetTickCount() - mousepostime) > 2000) {
483 // m_pDasherInterface->SetLongParameter(LP_MOUSE_POS_BOX, -1);
487 // else if(mousepostime > 0) {
488 // secondwindow = false;
489 // firstwindow = true;
490 // m_pDasherInterface->SetLongParameter(LP_MOUSE_POS_BOX, 1);
495 // imousey = mousepos.y;
497 // imousex = mousepos.x;
499 // if(m_pDasherInterface->GetBoolParameter(BP_NUMBER_DIMENSIONS) == true) {
500 // double scalefactor;
501 // if(yscaling == 0) {
502 // scalefactor = 2.0;
505 // scalefactor = m_pScreen->GetHeight() / yscaling;
507 // imousey -= m_pScreen->GetHeight() / 2;
508 // imousey *= scalefactor;
509 // imousey += m_pScreen->GetHeight() / 2;
512 // if((GetTickCount() - previoustime) > 200) {
513 // if(firstwindow == true) {
514 // m_pDasherInterface->SetLongParameter(LP_MOUSE_POS_BOX, 1);
516 // else if(secondwindow == true) {
517 // m_pDasherInterface->SetLongParameter(LP_MOUSE_POS_BOX, 2);
520 // previoustime = GetTickCount();
526 //// if(m_pDasherInterface->GetBoolParameter(BP_WINDOW_PAUSE) == true) {
527 // // RECT windowrect;
529 //// GetWindowRect(m_hwnd, &windowrect);
530 // // if(mousepos.y > windowrect.bottom || mousepos.y < windowrect.top || mousepos.x > windowrect.right || mousepos.x < windowrect.left)
534 // ScreenToClient(m_hwnd, &mousepos);
535 // imousey = mousepos.y;
536 // imousex = mousepos.x;
538 // if(m_pDasherInterface->GetBoolParameter(BP_NUMBER_DIMENSIONS) == true) {
539 // double scalefactor;
540 // if(yscaling == 0) {
544 // scalefactor = m_pScreen->GetHeight() / yscaling;
546 // imousey -= m_pScreen->GetHeight() / 2;
547 // imousey *= scalefactor;
548 // imousey += m_pScreen->GetHeight() / 2;
551 DWORD dwTicks
= GetTickCount();
553 // If not paused need to consider stop on idle
554 if( !m_pDasherInterface
->GetBoolParameter(BP_DASHER_PAUSED
) )
556 // only pause if button is not down
557 if( !m_bButtonDown
&& m_pDasherInterface
->GetBoolParameter(BP_STOP_IDLE
) )
559 if (dwTicks
- m_dwTicksLastEvent
> m_pDasherInterface
->GetLongParameter(LP_STOP_IDLETIME
) )
561 // idle time exceeded
562 m_pDasherInterface
->PauseAt(0, 0);
567 m_pDasherInterface
->NewFrame(dwTicks
, false);//TapOn(imousex, imousey, GetTickCount());
570 void CCanvas::centrecursor() {
572 mousepos
.x
= m_pScreen
->GetWidth() / 2;
574 mousepos
.y
= m_pScreen
->GetHeight() / 2;
576 ClientToScreen( &mousepos
);
578 SetCursorPos(mousepos
.x
, mousepos
.y
);
582 void CCanvas::MousePosStart(bool Value
) {
585 secondwindow
= false;
589 /////////////////////////////////////////////////////////////////////////////
591 void CCanvas::StartStop() {
596 m_pDasherInterface
->Unpause(GetTickCount());
598 secondwindow
= false;
603 m_pDasherInterface
->PauseAt(0, 0);
605 // if (speakonstop==true) { // FIXME - reimplement this
606 // m_DasherEditBox->speak(2);
612 /////////////////////////////////////////////////////////////////////////////
614 // Gets the size of the canvas in screen coordinates. Need if we
615 // want to log mouse positions normalized by the size of the
617 bool CCanvas::GetCanvasSize(int& iTop
, int& iLeft
, int& iBottom
, int& iRight
)
622 if (GetWindowRect( &sWindowRect
))
624 iTop
= sWindowRect
.top
;
625 iLeft
= sWindowRect
.left
;
626 iBottom
= sWindowRect
.bottom
;
627 iRight
= sWindowRect
.right
;
635 void CCanvas::HandleEvent(Dasher::CEvent
*pEvent
) {
637 if(pEvent
->m_iEventType
== 1) {
638 Dasher::CParameterNotificationEvent
* pEvt(static_cast < Dasher::CParameterNotificationEvent
* >(pEvent
));
639 switch (pEvt
->m_iParameter
) {
641 m_pScreen
->SetFont(m_pDasherInterface
->GetStringParameter(SP_DASHER_FONT
));
643 /* case BP_SOCKET_INPUT_ENABLE:
644 OutputDebugString(TEXT("Processing BP_SOCKET_INPUT_ENABLE change\n"));
645 if(GetBoolParameter(BP_SOCKET_INPUT_ENABLE)) {
646 if(!m_pSocketInput->isListening()) {
647 m_pSocketInput->StartListening();
649 m_pDasherInterface->SetInput(1);
652 if(m_pSocketInput != NULL) {
653 m_pSocketInput->StopListening();
655 m_pDasherInterface->SetInput(0);