| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625 |
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
- #include "stdafx.h"
- #include <stdarg.h>
- #ifdef AFXCTL_CORE2_SEG
- #pragma code_seg(AFXCTL_CORE2_SEG)
- #endif
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- #define new DEBUG_NEW
- #pragma warning(disable: 4706) // assignment within conditional
- /////////////////////////////////////////////////////////////////////////////
- // Stock event mask
- #define STOCKEVENT_CLICK 0x00000001
- #define STOCKEVENT_DBLCLICK 0x00000002
- #define STOCKEVENT_KEYDOWN 0x00000004
- #define STOCKEVENT_KEYPRESS 0x00000008
- #define STOCKEVENT_KEYUP 0x00000010
- #define STOCKEVENT_MOUSEDOWN 0x00000020
- #define STOCKEVENT_MOUSEMOVE 0x00000040
- #define STOCKEVENT_MOUSEUP 0x00000080
- #define STOCKEVENT_ERROR 0x00000100
- #define STOCKEVENT_READYSTATECHANGE 0x00000200
- #define STOCKEVENTS_MOUSE 0x000000A3 // Click, DblClick, MouseDown, MouseUp
- AFX_STATIC_DATA const DWORD _afxStockEvents[] =
- {
- STOCKEVENT_CLICK, // -600
- STOCKEVENT_DBLCLICK, // -601
- STOCKEVENT_KEYDOWN, // -602
- STOCKEVENT_KEYPRESS, // -603
- STOCKEVENT_KEYUP, // -604
- STOCKEVENT_MOUSEDOWN, // -605
- STOCKEVENT_MOUSEMOVE, // -606
- STOCKEVENT_MOUSEUP, // -607
- STOCKEVENT_ERROR, // -608
- STOCKEVENT_READYSTATECHANGE, // -609
- };
- void COleControl::InitStockEventMask()
- {
- const AFX_EVENTMAP* pEventMap = GetEventMap();
- const AFX_EVENTMAP_ENTRY* pEntry;
- ASSERT(pEventMap != NULL);
- // If stock event mask is already initialized, we're outta here.
- if (*pEventMap->lpStockEventMask != (DWORD)-1)
- return;
- AfxLockGlobals(CRIT_STOCKMASK);
- if (*pEventMap->lpStockEventMask == (DWORD)-1)
- {
- const AFX_EVENTMAP* pEventMapTop = pEventMap;
- DWORD dwStockEventMask = 0;
- while (pEventMap != NULL)
- {
- pEntry = pEventMap->lpEntries;
- while (pEntry != NULL && pEntry->pszName != NULL)
- {
- int nIndex = DISPID_CLICK - pEntry->dispid;
- DWORD dwFlag;
- if ((pEntry->flags & afxEventStock) && (nIndex >= 0) &&
- (nIndex < _countof(_afxStockEvents)) &&
- (dwFlag = _afxStockEvents[nIndex]) != 0)
- {
- dwStockEventMask |= dwFlag;
- }
- ++pEntry;
- }
- // check base class
- pEventMap = pEventMap->lpBaseEventMap;
- }
- *pEventMapTop->lpStockEventMask = dwStockEventMask;
- }
- AfxUnlockGlobals(CRIT_STOCKMASK);
- }
- /////////////////////////////////////////////////////////////////////////////
- // Event map operations
- const AFX_EVENTMAP* COleControl::GetEventMap() const
- {
- return &eventMap;
- }
- const AFX_EVENTMAP_ENTRY* COleControl::GetEventMapEntry(
- LPCTSTR pszName,
- DISPID* pDispid) const
- {
- ASSERT(pszName != NULL);
- ASSERT(pDispid != NULL);
- const AFX_EVENTMAP* pEventMap = GetEventMap();
- const AFX_EVENTMAP_ENTRY* pEntry;
- DISPID dispid = MAKELONG(1, 0);
- while (pEventMap != NULL)
- {
- pEntry = pEventMap->lpEntries;
- // Scan entries in this event map
- if (pEntry != NULL)
- {
- while (pEntry->pszName != NULL)
- {
- if (lstrcmp(pEntry->pszName, pszName) == 0)
- {
- if (pEntry->dispid != DISPID_UNKNOWN)
- dispid = pEntry->dispid;
- *pDispid = dispid;
- return pEntry;
- }
- ++pEntry;
- ++dispid;
- }
- }
- // If we didn't find it, go to the base class's event map
- pEventMap = pEventMap->lpBaseEventMap;
- dispid = MAKELONG(1, HIWORD(dispid)+1);
- }
- // If we reach here, the event isn't supported
- return NULL;
- }
- void COleControl::FireEventV(DISPID dispid, BYTE* pbParams,
- va_list argList)
- {
- COleDispatchDriver driver;
- POSITION pos = m_xEventConnPt.GetStartPosition();
- LPDISPATCH pDispatch;
- while (pos != NULL)
- {
- pDispatch = (LPDISPATCH)m_xEventConnPt.GetNextConnection(pos);
- ASSERT(pDispatch != NULL);
- driver.AttachDispatch(pDispatch, FALSE);
- TRY
- driver.InvokeHelperV(dispid, DISPATCH_METHOD, VT_EMPTY, NULL,
- pbParams, argList);
- END_TRY
- driver.DetachDispatch();
- }
- }
- void AFX_CDECL COleControl::FireEvent(DISPID dispid, BYTE* pbParams, ...)
- {
- va_list argList;
- va_start(argList, pbParams);
- FireEventV(dispid, pbParams, argList);
- va_end(argList);
- }
- /////////////////////////////////////////////////////////////////////////////
- // Helper function for stock events
- short AFXAPI _AfxShiftState()
- {
- BOOL bShift = (GetKeyState(VK_SHIFT) < 0);
- BOOL bCtrl = (GetKeyState(VK_CONTROL) < 0);
- BOOL bAlt = (GetKeyState(VK_MENU) < 0);
- return (short)(bShift + (bCtrl << 1) + (bAlt << 2));
- }
- /////////////////////////////////////////////////////////////////////////////
- // Window message handlers for stock events
- void COleControl::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- HWND hWndSave = m_hWnd;
- USHORT nCharShort = (USHORT)nChar;
- KeyDown(&nCharShort);
- if ((m_hWnd == hWndSave) && (nCharShort != 0))
- DefWindowProc(WM_SYSKEYDOWN, nCharShort, MAKELONG(nRepCnt, nFlags));
- }
- void COleControl::OnSysKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- HWND hWndSave = m_hWnd;
- USHORT nCharShort = (USHORT)nChar;
- KeyUp(&nCharShort);
- if ((m_hWnd == hWndSave) && (nCharShort != 0))
- DefWindowProc(WM_SYSKEYUP, nCharShort, MAKELONG(nRepCnt, nFlags));
- }
- void COleControl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- HWND hWndSave = m_hWnd;
- USHORT nCharShort = (USHORT)nChar;
- KeyDown(&nCharShort);
- if ((m_hWnd == hWndSave) && (nCharShort != 0))
- DefWindowProc(WM_KEYDOWN, nCharShort, MAKELONG(nRepCnt, nFlags));
- }
- void COleControl::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- HWND hWndSave = m_hWnd;
- USHORT nCharShort = (USHORT)nChar;
- KeyUp(&nCharShort);
- if ((m_hWnd == hWndSave) && (nCharShort != 0))
- DefWindowProc(WM_KEYUP, nCharShort, MAKELONG(nRepCnt, nFlags));
- }
- void COleControl::KeyUp(USHORT* pnChar)
- {
- if (GetStockEventMask() & STOCKEVENT_KEYUP)
- {
- USHORT nShiftState = _AfxShiftState();
- FireKeyUp(pnChar, nShiftState);
- // If handler set *pnChar to zero, cancel further processing.
- if (*pnChar != 0)
- OnKeyUpEvent(*pnChar, nShiftState);
- }
- }
- void COleControl::KeyDown(USHORT* pnChar)
- {
- if (GetStockEventMask() & STOCKEVENT_KEYDOWN)
- {
- USHORT nShiftState = _AfxShiftState();
- FireKeyDown(pnChar, nShiftState);
- // If handler set *pnChar to zero, cancel further processing.
- if (*pnChar != 0)
- OnKeyDownEvent(*pnChar, nShiftState);
- }
- }
- AFX_STATIC void AFXAPI _AfxPostTrailByte(CWnd* pWnd, BYTE bTrailByte)
- {
- // Force new trail byte to the front of the queue.
- pWnd->PostMessage(WM_QUEUE_SENTINEL);
- pWnd->PostMessage(WM_CHAR, bTrailByte);
- MSG msg;
- while (::PeekMessage(&msg, NULL, 0, 0, PM_NOYIELD | PM_REMOVE) &&
- (msg.message != WM_QUEUE_SENTINEL))
- {
- ::PostMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam);
- }
- ASSERT(msg.message == WM_QUEUE_SENTINEL);
- ASSERT(msg.hwnd == pWnd->m_hWnd);
- }
- UINT COleControl::OnGetDlgCode()
- {
- // If we're firing KeyPress, prevent the container from stealing WM_CHAR.
- return (IsSubclassedControl() ? CWnd::OnGetDlgCode() : 0) |
- ((GetStockEventMask() & STOCKEVENT_KEYPRESS) ? DLGC_WANTCHARS : 0);
- }
- void COleControl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- USHORT nCharShort = (USHORT)nChar;
- USHORT nCharSave = nCharShort;
- BOOL bLeadByte = IsDBCSLeadByte((BYTE)nCharShort);
- MSG msg;
- if (GetStockEventMask() & STOCKEVENT_KEYPRESS)
- {
- if (bLeadByte)
- {
- // We have the lead-byte of a DBCS character. Peek for the
- // next WM_CHAR message, which will contain the other byte.
- BOOL bMessage;
- VERIFY(bMessage = ::PeekMessage(&msg, m_hWnd, WM_CHAR, WM_CHAR,
- PM_NOYIELD | PM_NOREMOVE));
- // Combine the bytes to form the DBCS character.
- if (bMessage)
- nCharShort = (USHORT)((nCharShort << 8) | msg.wParam);
- }
- HWND hWndSave = m_hWnd;
- nCharSave = nCharShort;
- FireKeyPress(&nCharShort);
- // If handler set nCharShort to zero, cancel further processing.
- if (nCharShort != 0)
- OnKeyPressEvent(nCharShort);
- if (m_hWnd != hWndSave)
- return;
- }
- if (nCharShort != 0)
- {
- if (nCharSave != nCharShort)
- {
- nChar = nCharShort;
- // Event handler has changed the character.
- BOOL bNewLeadByte = IsDBCSLeadByte(HIBYTE(nCharShort));
- if (bLeadByte)
- {
- if (bNewLeadByte)
- {
- // Event handler changed character from DBCS to DBCS:
- // Remove the old trail byte and post the new one.
- VERIFY(::PeekMessage(&msg, m_hWnd, WM_CHAR, WM_CHAR,
- PM_NOYIELD | PM_REMOVE));
- _AfxPostTrailByte(this, LOBYTE(nCharShort));
- nChar = HIBYTE(nCharShort);
- }
- else
- {
- // Event handler changed character from DBCS to SBCS:
- // Remove the second byte from the queue, and forward
- // along the new single-byte character.
- VERIFY(::PeekMessage(&msg, m_hWnd, WM_CHAR, WM_CHAR,
- PM_NOYIELD | PM_REMOVE));
- }
- }
- else
- {
- if (bNewLeadByte)
- {
- // Event handler changed character from SBCS to DBCS:
- // Post the new trail byte.
- _AfxPostTrailByte(this, LOBYTE(nCharShort));
- nChar = HIBYTE(nCharShort);
- }
- }
- }
- DefWindowProc(WM_CHAR, nChar, MAKELONG(nRepCnt, nFlags));
- }
- if (bLeadByte)
- {
- // Cleanup after processing a DBCS character:
- // Remove the next WM_CHAR message (containing the second byte) from
- // the message queue, UNLESS we're subclassing an Edit, ListBox, or
- // ComboBox control.
- TCHAR szClassName[10];
- if ((!::GetClassName(m_hWnd, szClassName, 10)) || // didn't get class
- (lstrcmpi(szClassName, _T("Edit")) && // not Edit
- lstrcmpi(szClassName, _T("ListBox")) && // not ListBox
- lstrcmpi(szClassName, _T("ComboBox")))) // not ComboBox
- {
- VERIFY(::PeekMessage(&msg, m_hWnd, WM_CHAR, WM_CHAR,
- PM_NOYIELD | PM_REMOVE));
- }
- }
- }
- void COleControl::OnKeyPressEvent(USHORT)
- {
- // Can be overridden by subclass
- }
- void COleControl::OnKeyDownEvent(USHORT, USHORT)
- {
- // Can be overridden by subclass
- }
- void COleControl::OnKeyUpEvent(USHORT, USHORT)
- {
- // Can be overridden by subclass
- }
- void COleControl::ButtonDown(USHORT iButton, UINT, CPoint point)
- {
- DWORD dwStockEventMask = GetStockEventMask();
- if ((dwStockEventMask & STOCKEVENTS_MOUSE) || m_bPendingUIActivation)
- {
- if (m_iButtonState == 0)
- SetCapture();
- m_iButtonState |= iButton;
- if (dwStockEventMask & STOCKEVENT_MOUSEDOWN)
- FireMouseDown(iButton, _AfxShiftState(), point.x, point.y);
- m_iDblClkState &= ~iButton;
- }
- }
- void COleControl::ButtonUp(USHORT iButton, UINT, CPoint point)
- {
- if (m_iButtonState != 0)
- {
- m_iButtonState &= ~iButton;
- if (m_iButtonState == 0)
- ReleaseCapture();
- DWORD dwStockEventMask = GetStockEventMask();
- if (dwStockEventMask & STOCKEVENT_MOUSEUP)
- FireMouseUp(iButton, _AfxShiftState(), point.x, point.y);
- if ((dwStockEventMask & STOCKEVENT_CLICK) &&
- !(m_iDblClkState & iButton))
- {
- CRect rect;
- GetClientRect(&rect);
- if (rect.PtInRect(point))
- OnClick(iButton);
- }
- m_iDblClkState &= ~iButton;
- }
- }
- void COleControl::ButtonDblClk(USHORT iButton, UINT, CPoint)
- {
- DWORD dwStockEventMask = GetStockEventMask();
- if (dwStockEventMask & STOCKEVENTS_MOUSE)
- {
- SetCapture();
- m_iButtonState |= iButton;
- if (dwStockEventMask & STOCKEVENT_DBLCLICK)
- {
- FireDblClick();
- m_iDblClkState |= iButton;
- }
- }
- }
- void COleControl::OnMouseMove(UINT /*nFlags*/, CPoint point)
- {
- if (GetStockEventMask() & STOCKEVENT_MOUSEMOVE)
- {
- HWND hWndSave = m_hWnd;
- FireMouseMove((short)m_iButtonState, _AfxShiftState(), point.x, point.y);
- if (m_hWnd != hWndSave)
- return;
- }
- Default();
- }
- void COleControl::OnLButtonDown(UINT nFlags, CPoint point)
- {
- OnButtonDown(LEFT_BUTTON, nFlags, point);
- }
- void COleControl::OnLButtonUp(UINT nFlags, CPoint point)
- {
- OnButtonUp(LEFT_BUTTON, nFlags, point);
- }
- void COleControl::OnLButtonDblClk(UINT nFlags, CPoint point)
- {
- OnButtonDblClk(LEFT_BUTTON, nFlags, point);
- }
- void COleControl::OnMButtonDown(UINT nFlags, CPoint point)
- {
- OnButtonDown(MIDDLE_BUTTON, nFlags, point);
- }
- void COleControl::OnMButtonUp(UINT nFlags, CPoint point)
- {
- OnButtonUp(MIDDLE_BUTTON, nFlags, point);
- }
- void COleControl::OnMButtonDblClk(UINT nFlags, CPoint point)
- {
- OnButtonDblClk(MIDDLE_BUTTON, nFlags, point);
- }
- void COleControl::OnRButtonDown(UINT nFlags, CPoint point)
- {
- OnButtonDown(RIGHT_BUTTON, nFlags, point);
- }
- void COleControl::OnRButtonUp(UINT nFlags, CPoint point)
- {
- OnButtonUp(RIGHT_BUTTON, nFlags, point);
- }
- void COleControl::OnRButtonDblClk(UINT nFlags, CPoint point)
- {
- OnButtonDblClk(RIGHT_BUTTON, nFlags, point);
- }
- void COleControl::OnButtonDown(USHORT nButton, UINT nFlags, CPoint point)
- {
- HWND hWndSave = m_hWnd;
- if (nButton == LEFT_BUTTON)
- SetFocus();
- ButtonDown(nButton, nFlags, point);
- if (m_hWnd != hWndSave)
- return;
- Default();
- }
- void COleControl::OnButtonUp(USHORT nButton, UINT nFlags, CPoint point)
- {
- HWND hWndSave = m_hWnd;
- Default();
- ButtonUp(nButton, nFlags, point);
- if (m_hWnd != hWndSave)
- return;
- if (m_bInPlaceActive && !m_bUIActive && m_bPendingUIActivation)
- {
- m_bPendingUIActivation = FALSE;
- HWND hWndFocus = ::GetFocus();
- if (hWndFocus == m_hWnd || ::IsChild(m_hWnd, hWndFocus))
- OnActivateInPlace(TRUE, NULL);
- }
- }
- void COleControl::OnButtonDblClk(USHORT nButton, UINT nFlags, CPoint point)
- {
- HWND hWndSave = m_hWnd;
- ButtonDblClk(nButton, nFlags, point);
- if (m_hWnd != hWndSave)
- return;
- Default();
- }
- void COleControl::OnCancelMode()
- {
- CWnd::OnCancelMode();
- if ((m_iButtonState != 0) || (m_iDblClkState != 0))
- {
- ReleaseCapture();
- m_iButtonState = 0;
- m_iDblClkState = 0;
- }
- }
- void COleControl::OnClick(USHORT /*iButton*/)
- {
- // May be overridden by subclass
- if (GetStockEventMask() & STOCKEVENT_CLICK)
- FireClick();
- }
- /////////////////////////////////////////////////////////////////////////////
- // Error event
- #define ERROR_PARAMS \
- EVENT_PARAM(VTS_I2 VTS_PBSTR VTS_SCODE VTS_BSTR VTS_BSTR VTS_I4 VTS_PBOOL)
- void COleControl::FireError(SCODE scode, LPCTSTR lpszDescription, UINT nHelpID)
- {
- USES_CONVERSION;
- ExternalAddRef(); // "Insurance" addref -- keeps control alive.
- BSTR bstrDescription = ::SysAllocString(T2COLE(lpszDescription));
- LPCTSTR lpszSource = AfxGetAppName();
- LPCTSTR lpszHelpFile = _T("");
- if (nHelpID != 0)
- lpszHelpFile = AfxGetApp()->m_pszHelpFilePath;
- if (lpszHelpFile == NULL)
- lpszHelpFile = _T("");
- BOOL bCancelDisplay = FALSE;
- FireEvent(DISPID_ERROREVENT, ERROR_PARAMS, (WORD)SCODE_CODE(scode),
- &bstrDescription, scode, lpszSource, lpszHelpFile, (DWORD)nHelpID,
- &bCancelDisplay);
- if (!bCancelDisplay)
- DisplayError(scode, OLE2CT(bstrDescription), lpszSource, lpszHelpFile, nHelpID);
- ::SysFreeString(bstrDescription);
- ExternalRelease();
- }
- void COleControl::DisplayError(SCODE /*scode*/, LPCTSTR lpszDescription,
- LPCTSTR lpszSource, LPCTSTR /*lpszHelpFile*/, UINT /*nHelpID*/)
- {
- // May be overridden by subclass.
- MessageBox(lpszDescription, lpszSource);
- }
- /////////////////////////////////////////////////////////////////////////////
- // Force any extra compiler-generated code into AFX_INIT_SEG
- #ifdef AFX_INIT_SEG
- #pragma code_seg(AFX_INIT_SEG)
- #endif
|