Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
3.9 KiB

  1. /*++
  2. Copyright (c) 1985 - 1999, Microsoft Corporation
  3. Module Name:
  4. mouse.cpp
  5. Abstract:
  6. This file implements the mouse sink in the ImmIfIME Class.
  7. Author:
  8. Revision History:
  9. Notes:
  10. --*/
  11. #include "private.h"
  12. #include "mouse.h"
  13. #include "template.h"
  14. #include "immif.h"
  15. #include "editses.h"
  16. #include "sink.h"
  17. #include "imeapp.h"
  18. ULONG
  19. CMouseSink::InternalAddRef(
  20. )
  21. {
  22. return ++m_ref;
  23. }
  24. ULONG
  25. CMouseSink::InternalRelease(
  26. )
  27. {
  28. ULONG cr = --m_ref;
  29. if (cr == 0) {
  30. delete this;
  31. }
  32. return cr;
  33. }
  34. HRESULT
  35. CMouseSink::AdviseMouseSink(
  36. HIMC hImc,
  37. ITfRangeACP* range,
  38. ITfMouseSink* pSink,
  39. DWORD* pdwCookie
  40. )
  41. {
  42. if (m_prgMouseSinks == NULL)
  43. return E_FAIL;
  44. const IID *rgiid = &IID_ITfMouseSink;
  45. GENERICSINK *pgs;
  46. HRESULT hr;
  47. hr = GenericAdviseSink(IID_ITfMouseSink, pSink, &rgiid, m_prgMouseSinks, 1, pdwCookie, &pgs);
  48. if (hr == S_OK) {
  49. pgs->uPrivate = (UINT_PTR) new tagPRIVATE_MOUSESINK;
  50. if (pgs->uPrivate) {
  51. ((LPPRIVATE_MOUSESINK)pgs->uPrivate)->range.Attach(range);
  52. range->AddRef();
  53. ((LPPRIVATE_MOUSESINK)pgs->uPrivate)->hImc = hImc;
  54. }
  55. }
  56. return hr;
  57. }
  58. HRESULT
  59. CMouseSink::UnadviseMouseSink(
  60. DWORD dwCookie
  61. )
  62. {
  63. if (m_prgMouseSinks == NULL)
  64. return E_FAIL;
  65. HRESULT hr;
  66. LPPRIVATE_MOUSESINK pPrivMouseSink = NULL;
  67. hr = GenericUnadviseSink(m_prgMouseSinks, 1, dwCookie, (UINT_PTR *)&pPrivMouseSink);
  68. if (hr == S_OK) {
  69. if (pPrivMouseSink) {
  70. delete pPrivMouseSink;
  71. }
  72. }
  73. return hr;
  74. }
  75. LRESULT
  76. CMouseSink::MsImeMouseHandler(
  77. ULONG uEdge,
  78. ULONG uQuadrant,
  79. ULONG dwBtnStatus,
  80. IMCLock& imc,
  81. ImmIfIME* ImmIfIme
  82. )
  83. {
  84. LONG acpStart;
  85. LONG cch;
  86. ULONG uRangeEdgeMin;
  87. ULONG uRangeEdgeMax;
  88. HRESULT hr;
  89. /*
  90. * Find out specified range in whole text's range
  91. */
  92. BOOL fEaten = FALSE;
  93. for (int i = 0; i < m_prgMouseSinks->Count(); i++) {
  94. GENERICSINK* pgs;
  95. LPPRIVATE_MOUSESINK pPrivMouseSink;
  96. pgs = m_prgMouseSinks->GetPtr(i);
  97. pPrivMouseSink = (LPPRIVATE_MOUSESINK)pgs->uPrivate;
  98. if ((HIMC)imc != pPrivMouseSink->hImc)
  99. continue;
  100. // test: does this sink cover the specified edge?
  101. pPrivMouseSink->range->GetExtent(&acpStart, &cch);
  102. uRangeEdgeMin = acpStart;
  103. uRangeEdgeMax = acpStart + cch;
  104. //
  105. // Get GUID_PROP_MSIMTF_READONLY margin.
  106. //
  107. Interface_Creator<ImmIfEditSession> _pEditSession(
  108. new ImmIfEditSession(ESCB_GET_READONLY_PROP_MARGIN,
  109. ImmIfIme->GetClientId(),
  110. ImmIfIme->GetCurrentInterface(),
  111. imc)
  112. );
  113. if (_pEditSession.Valid())
  114. {
  115. if (SUCCEEDED(_pEditSession->RequestEditSession(TF_ES_READWRITE | TF_ES_SYNC,
  116. &pPrivMouseSink->range, &cch)))
  117. {
  118. uEdge += cch;
  119. }
  120. }
  121. if (uEdge < uRangeEdgeMin)
  122. continue;
  123. if (uEdge == uRangeEdgeMin && uQuadrant < 2)
  124. continue;
  125. if (uEdge > uRangeEdgeMax)
  126. continue;
  127. if (uEdge == uRangeEdgeMax && uQuadrant > 1)
  128. continue;
  129. //
  130. // Call OnMouseEvent
  131. //
  132. hr = ((ITfMouseSink*)pgs->pSink)->OnMouseEvent(uEdge - uRangeEdgeMin /* adjust uEdge for this range's frame of reference */,
  133. uQuadrant, dwBtnStatus, &fEaten);
  134. if (hr == S_OK && fEaten)
  135. return 1L;
  136. break; // we already found a covered range, don't bother querying any others
  137. }
  138. return IMEMOUSERET_NOTHANDLED;
  139. }