3 /////////////////////////////////////////////////////////////////////////////
5 // Copyright (c) 2002 Iain Murray, Inference Group, Cavendish, Cambridge.
7 /////////////////////////////////////////////////////////////////////////////
9 #include "..\Common\WinCommon.h"
13 #include "../Dasher.h"
14 //#include "..\..\DasherCore\DasherInterfaceBase.h"
18 #define PRESSED 0x8000
19 #define REPEAT 0x40000000
20 using namespace Dasher
;
22 #include "../TabletPC/SystemInfo.h"
25 /////////////////////////////////////////////////////////////////////////////
27 CCanvas::CCanvas(CDasher
*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(Dasher::CDasherInterfaceBase
* 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
) {
442 m_pDasherInterface
->Main();
447 void CCanvas::DoFrame()
450 GetCursorPos(&mousepos2
);
452 ScreenToClient(&mousepos2
);
455 GetCursorPos(&mousepos
);
457 // if(running == 0) {
458 // ScreenToClient(m_hwnd, &mousepos);
459 // if(m_pDasherInterface->GetBoolParameter(BP_MOUSEPOS_MODE) == true) // configuration option
461 // // DASHER_TRACEOUTPUT("first:%d second:%d %d\n",firstwindow,secondwindow,m_iMousePosDist);
462 // if(firstwindow != true && secondwindow != true) {
463 // m_pDasherInterface->SetLongParameter(LP_MOUSE_POS_BOX, 1);
464 // firstwindow = true;
466 // int mouseDist = m_pDasherInterface->GetLongParameter(LP_MOUSEPOSDIST);
467 // if(mousepos.y > m_pScreen->GetHeight() / 2 - mouseDist - 50 && mousepos.y < m_pScreen->GetHeight() / 2 - mouseDist + 50 && firstwindow == true) {
468 // // Mouse is in the top box
469 // if(mousepostime == 0) {
470 // mousepostime = GetTickCount();
472 // else if((GetTickCount() - mousepostime) > 2000) {
473 // firstwindow = false;
474 // secondwindow = true;
476 // m_pDasherInterface->SetLongParameter(LP_MOUSE_POS_BOX, 2);
479 // else if(firstwindow == true) {
482 // if(secondwindow == true) {
483 // if(mousepos.y < m_pScreen->GetHeight() / 2 + mouseDist + 50 && mousepos.y > (m_pScreen->GetHeight() / 2 + mouseDist - 50)) {
484 // // In second window
485 // if(mousepostime == 0) {
486 // mousepostime = GetTickCount();
488 // else if((GetTickCount() - mousepostime) > 2000) {
489 // m_pDasherInterface->SetLongParameter(LP_MOUSE_POS_BOX, -1);
493 // else if(mousepostime > 0) {
494 // secondwindow = false;
495 // firstwindow = true;
496 // m_pDasherInterface->SetLongParameter(LP_MOUSE_POS_BOX, 1);
501 // imousey = mousepos.y;
503 // imousex = mousepos.x;
505 // if(m_pDasherInterface->GetBoolParameter(BP_NUMBER_DIMENSIONS) == true) {
506 // double scalefactor;
507 // if(yscaling == 0) {
508 // scalefactor = 2.0;
511 // scalefactor = m_pScreen->GetHeight() / yscaling;
513 // imousey -= m_pScreen->GetHeight() / 2;
514 // imousey *= scalefactor;
515 // imousey += m_pScreen->GetHeight() / 2;
518 // if((GetTickCount() - previoustime) > 200) {
519 // if(firstwindow == true) {
520 // m_pDasherInterface->SetLongParameter(LP_MOUSE_POS_BOX, 1);
522 // else if(secondwindow == true) {
523 // m_pDasherInterface->SetLongParameter(LP_MOUSE_POS_BOX, 2);
526 // previoustime = GetTickCount();
532 //// if(m_pDasherInterface->GetBoolParameter(BP_WINDOW_PAUSE) == true) {
533 // // RECT windowrect;
535 //// GetWindowRect(m_hwnd, &windowrect);
536 // // if(mousepos.y > windowrect.bottom || mousepos.y < windowrect.top || mousepos.x > windowrect.right || mousepos.x < windowrect.left)
540 // ScreenToClient(m_hwnd, &mousepos);
541 // imousey = mousepos.y;
542 // imousex = mousepos.x;
544 // if(m_pDasherInterface->GetBoolParameter(BP_NUMBER_DIMENSIONS) == true) {
545 // double scalefactor;
546 // if(yscaling == 0) {
550 // scalefactor = m_pScreen->GetHeight() / yscaling;
552 // imousey -= m_pScreen->GetHeight() / 2;
553 // imousey *= scalefactor;
554 // imousey += m_pScreen->GetHeight() / 2;
557 DWORD dwTicks
= GetTickCount();
559 // If not paused need to consider stop on idle
560 if( !m_pDasherInterface
->GetBoolParameter(BP_DASHER_PAUSED
) )
562 // only pause if button is not down
563 if( !m_bButtonDown
&& m_pDasherInterface
->GetBoolParameter(BP_STOP_IDLE
) )
565 if (dwTicks
- m_dwTicksLastEvent
> m_pDasherInterface
->GetLongParameter(LP_STOP_IDLETIME
) )
567 // idle time exceeded
568 m_pDasherInterface
->PauseAt(0, 0);
573 m_pDasherInterface
->NewFrame(dwTicks
, false);//TapOn(imousex, imousey, GetTickCount());
576 void CCanvas::centrecursor() {
578 mousepos
.x
= m_pScreen
->GetWidth() / 2;
580 mousepos
.y
= m_pScreen
->GetHeight() / 2;
582 ClientToScreen( &mousepos
);
584 SetCursorPos(mousepos
.x
, mousepos
.y
);
588 void CCanvas::MousePosStart(bool Value
) {
591 secondwindow
= false;
595 /////////////////////////////////////////////////////////////////////////////
597 void CCanvas::StartStop() {
602 m_pDasherInterface
->Unpause(GetTickCount());
604 secondwindow
= false;
609 m_pDasherInterface
->PauseAt(0, 0);
611 // if (speakonstop==true) { // FIXME - reimplement this
612 // m_DasherEditBox->speak(2);
618 /////////////////////////////////////////////////////////////////////////////
620 // Gets the size of the canvas in screen coordinates. Need if we
621 // want to log mouse positions normalized by the size of the
623 bool CCanvas::GetCanvasSize(int& iTop
, int& iLeft
, int& iBottom
, int& iRight
)
628 if (GetWindowRect( &sWindowRect
))
630 iTop
= sWindowRect
.top
;
631 iLeft
= sWindowRect
.left
;
632 iBottom
= sWindowRect
.bottom
;
633 iRight
= sWindowRect
.right
;
641 void CCanvas::HandleEvent(Dasher::CEvent
*pEvent
) {
643 if(pEvent
->m_iEventType
== 1) {
644 Dasher::CParameterNotificationEvent
* pEvt(static_cast < Dasher::CParameterNotificationEvent
* >(pEvent
));
645 switch (pEvt
->m_iParameter
) {
647 m_pScreen
->SetFont(m_pDasherInterface
->GetStringParameter(SP_DASHER_FONT
));
649 /* case BP_SOCKET_INPUT_ENABLE:
650 OutputDebugString(TEXT("Processing BP_SOCKET_INPUT_ENABLE change\n"));
651 if(GetBoolParameter(BP_SOCKET_INPUT_ENABLE)) {
652 if(!m_pSocketInput->isListening()) {
653 m_pSocketInput->StartListening();
655 m_pDasherInterface->SetInput(1);
658 if(m_pSocketInput != NULL) {
659 m_pSocketInput->StopListening();
661 m_pDasherInterface->SetInput(0);