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.

165 lines
3.4 KiB

  1. /*++
  2. Copyright (c) 2001, 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 "editses.h"
  15. #include "msime.h"
  16. ULONG
  17. CMouseSink::InternalAddRef(
  18. )
  19. {
  20. return ++m_ref;
  21. }
  22. ULONG
  23. CMouseSink::InternalRelease(
  24. )
  25. {
  26. ULONG cr = --m_ref;
  27. if (cr == 0) {
  28. delete this;
  29. }
  30. return cr;
  31. }
  32. HRESULT
  33. CMouseSink::AdviseMouseSink(
  34. HIMC hImc,
  35. ITfRangeACP* range,
  36. ITfMouseSink* pSink,
  37. DWORD* pdwCookie
  38. )
  39. {
  40. if (m_prgMouseSinks == NULL)
  41. return E_FAIL;
  42. const IID *rgiid = &IID_ITfMouseSink;
  43. GENERICSINK *pgs;
  44. HRESULT hr;
  45. hr = GenericAdviseSink(IID_ITfMouseSink, pSink, &rgiid, m_prgMouseSinks, 1, pdwCookie, &pgs);
  46. if (hr == S_OK) {
  47. pgs->uPrivate = (UINT_PTR) new tagPRIVATE_MOUSESINK;
  48. if (pgs->uPrivate) {
  49. ((LPPRIVATE_MOUSESINK)pgs->uPrivate)->range.Attach(range);
  50. range->AddRef();
  51. ((LPPRIVATE_MOUSESINK)pgs->uPrivate)->hImc = hImc;
  52. }
  53. }
  54. return hr;
  55. }
  56. HRESULT
  57. CMouseSink::UnadviseMouseSink(
  58. DWORD dwCookie
  59. )
  60. {
  61. if (m_prgMouseSinks == NULL)
  62. return E_FAIL;
  63. HRESULT hr;
  64. LPPRIVATE_MOUSESINK pPrivMouseSink = NULL;
  65. hr = GenericUnadviseSink(m_prgMouseSinks, 1, dwCookie, (UINT_PTR *)&pPrivMouseSink);
  66. if (hr == S_OK) {
  67. if (pPrivMouseSink) {
  68. delete pPrivMouseSink;
  69. }
  70. }
  71. return hr;
  72. }
  73. LRESULT
  74. CMouseSink::MsImeMouseHandler(
  75. ULONG uEdge,
  76. ULONG uQuadrant,
  77. ULONG dwBtnStatus,
  78. IMCLock& imc
  79. )
  80. {
  81. LONG acpStart;
  82. LONG cch;
  83. ULONG uRangeEdgeMin;
  84. ULONG uRangeEdgeMax;
  85. HRESULT hr;
  86. /*
  87. * Find out specified range in whole text's range
  88. */
  89. BOOL fEaten = FALSE;
  90. for (int i = 0; i < m_prgMouseSinks->Count(); i++) {
  91. GENERICSINK* pgs;
  92. LPPRIVATE_MOUSESINK pPrivMouseSink;
  93. pgs = m_prgMouseSinks->GetPtr(i);
  94. pPrivMouseSink = (LPPRIVATE_MOUSESINK)pgs->uPrivate;
  95. if ((HIMC)imc != pPrivMouseSink->hImc)
  96. continue;
  97. // test: does this sink cover the specified edge?
  98. pPrivMouseSink->range->GetExtent(&acpStart, &cch);
  99. uRangeEdgeMin = acpStart;
  100. uRangeEdgeMax = acpStart + cch;
  101. //
  102. // Get GUID_PROP_MSIMTF_READONLY margin.
  103. //
  104. hr = EscbReadOnlyPropMargin(imc, &pPrivMouseSink->range, &cch);
  105. if (SUCCEEDED(hr))
  106. {
  107. uEdge += cch;
  108. }
  109. if (uEdge < uRangeEdgeMin)
  110. continue;
  111. if (uEdge == uRangeEdgeMin && uQuadrant < 2)
  112. continue;
  113. if (uEdge > uRangeEdgeMax)
  114. continue;
  115. if (uEdge == uRangeEdgeMax && uQuadrant > 1)
  116. continue;
  117. //
  118. // Call OnMouseEvent
  119. //
  120. hr = ((ITfMouseSink*)pgs->pSink)->OnMouseEvent(uEdge - uRangeEdgeMin /* adjust uEdge for this range's frame of reference */,
  121. uQuadrant, dwBtnStatus, &fEaten);
  122. if (hr == S_OK && fEaten)
  123. return 1L;
  124. break; // we already found a covered range, don't bother querying any others
  125. }
  126. return IMEMOUSERET_NOTHANDLED;
  127. }