home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-12-16 | 9.4 KB | 429 lines | [TEXT/CWIE] |
- // =================================================================================
- //
- // CEventSend.cpp ©1996 Microsoft Corporation All rights reserved.
- //
- // =================================================================================
-
- #include "ocheaders.h"
- #include <LArray.h>
- #include "CConnectionPoint.h"
- #include "CCPContainer.h"
- #include "CEventSend.h"
-
- /************* Local EventSend defines ****************/
- #define NUM_CONNECTIONS 1 // This control only has one connection point
- #define kIDLen 256 // max number of characters in the control ID (name)
- //
- // CEventSend::CEventSend
- //
-
- CEventSend::CEventSend(void) : CBaseControl()
- {
- CCPContainer* containerObj = nil;
-
- mOwnedFoci = EmptyFocusSet;
-
- // No message to display
- PLstrcpy(mMessage, "\p");
-
- mIdP = NULL;
- mLastMouseUpTime = ::TickCount() - ::GetDblTime();
-
- // Create the new connection point container object
- containerObj = new CCPContainer(NUM_CONNECTIONS);
-
- // Snag the interface pointer
- if ( containerObj )
- containerObj->QueryInterface(IID_IConnectionPointContainer, &mCPContainerP);
-
- // if we have a container object, allocate the connection points
- if ( mCPContainerP )
- // We support 1 connection point
- containerObj->AddConnectionPoint(IID_IStandardEvents);
- }
-
-
- //
- // CEventSend::~CEventSend
- //
-
- CEventSend::~CEventSend(void)
- {
- if (mIdP)
- delete [] mIdP;
- }
-
-
-
- //
- // CEventSend::FireEvent
- //
-
- STDMETHODIMP
- CEventSend::FireEvent(REFIID inRefID, Int32 inEventID, PlatformEvent* inEvent)
- {
- IEnumConnectionPoints* enumCP;
- IEnumConnections* enumC;
- CONNECTDATA connectData;
- IUnknown* eventTarget;
- IConnectionPoint* connectionPoint;
-
- // Get an enumerator for the connection points
- if ( SUCCEEDED(mCPContainerP->EnumConnectionPoints(&enumCP)) )
- {
- // Loop through all the connection points for this control
- while ( enumCP->Next(1, &connectionPoint, nil) == NOERROR )
- {
- // Get all the connections for this connection point
- if ( SUCCEEDED( connectionPoint->EnumConnections(&enumC) ))
- {
- // Loop through all the connections for this connection point
- while ( enumC->Next(1, &connectData, nil) == NOERROR )
- {
- // Get the interface implementation for this connection
- // if successful, fire the event
- if ( SUCCEEDED( connectData.pUnk->QueryInterface(inRefID, (void**) &eventTarget) ))
- FireOneEvent(inRefID, inEventID, eventTarget, inEvent);
- }
-
- // Release the enumerator
- enumC->Release();
- }
- }
-
- enumCP->Release();
- }
-
- return S_OK;
- }
-
-
- //
- // CEventSend::FireOneEvent
- //
-
- STDMETHODIMP
- CEventSend::FireOneEvent(REFIID inRefID, Int32 inEventID, IUnknown* inEventTarget, PlatformEvent* inEvent)
- {
- #pragma unused (inRefID)
- IStandardEvents* target = (IStandardEvents*) inEventTarget;
- IUnknown* unk;
-
- this->QueryInterface(IID_IUnknown, (void**) &unk);
-
- switch ( inEventID )
- {
- case DISPID_DBLCLICK:
- target->OnDoubleClick(unk, inEvent);
- break;
-
- case DISPID_KEYDOWN:
- target->OnKeyDown(unk, inEvent);
- break;
-
- case DISPID_AUTOKEY:
- target->OnAutoKey(unk, inEvent);
- break;
-
- case DISPID_KEYUP:
- target->OnKeyUp(unk, inEvent);
- break;
-
- case DISPID_MOUSEDOWN:
- target->OnMouseDown(unk, inEvent);
- break;
-
- case DISPID_MOUSEUP:
- target->OnMouseUp(unk, inEvent);
- break;
- }
-
- return S_OK;
- }
-
-
- //
- // CEventSend::IControl::Draw
- //
-
- STDMETHODIMP
- CEventSend::Draw(DrawContext* inContext)
- {
- Char8 id[kIDLen];
- FontInfo fInfo;
- Int16 curX;
- Int16 curY;
- RgnHandle saveClipRgn;
- Rect controlRect, newClipRect;
- Boolean8 overlap = false;
-
- if (inContext->DrawAspect != DVASPECT_CONTENT)
- return DV_E_DVASPECT;
-
- // Set the font and size
- ::TextFont(applFont);
- ::TextFace(0);
- ::TextMode(srcCopy);
- ::TextSize(12);
- ::GetFontInfo(&fInfo);
-
- // Erase the area and outline the frame (thicker if in focus)
- ::EraseRect(&inContext->Location);
- if (mOwnedFoci & KeyboardFocus) {
- ::PenSize(2, 2);
- }
- else {
- ::PenSize(1, 1);
- }
- ::FrameRect(&inContext->Location);
-
- // Save the current clip
- saveClipRgn = ::NewRgn();
- ::GetClip(saveClipRgn);
-
- controlRect = inContext->Location;
- ::InsetRect(&controlRect, 3, 3);
- overlap = SectRect(&controlRect, &((*saveClipRgn)->rgnBBox), &newClipRect);
-
- if (overlap)
- {
- // Reset the clip
- ::ClipRect(&newClipRect);
- }
-
- curX = inContext->Location.left+4;
- curY = inContext->Location.top+4;
-
- // Draw the control id (name) on the first line
- curY += fInfo.ascent;
- ::MoveTo(curX, curY);
- GetID(kIDLen, id);
- ::DrawText(id, 0, strlen(id));
-
- // Draw the message on the second line
- curY += fInfo.ascent + fInfo.descent + fInfo.leading;
- ::MoveTo(curX, curY);
- ::DrawString(mMessage);
-
- if (overlap)
- {
- // Restore the clip
- ::SetClip(saveClipRgn);
- }
- ::DisposeRgn(saveClipRgn);
-
- return S_OK;
- }
-
-
- //
- // CEventSend::IControl::GetID
- //
-
- STDMETHODIMP
- CEventSend::GetID(Int32 inBufferSize, Char8* outID)
- {
- if (mIdP)
- {
- Int32 IDLen = strlen(mIdP);
-
- if (IDLen > --inBufferSize)
- IDLen = inBufferSize;
-
- ::BlockMove(mIdP, outID, IDLen);
- *(outID + IDLen) = '\0';
- }
- else
- return CBaseControl::GetID(inBufferSize, outID);
-
- return S_OK;
- }
-
-
- //
- // CEventSend::IControl::DoMouse
- //
-
- STDMETHODIMP
- CEventSend::DoMouse(MouseEventType inMouseET, PlatformEvent* inEvent)
- {
- Boolean doInval = false;
-
- switch (inMouseET)
- {
- case MouseDown:
- if (( mOwnedFoci & KeyboardFocus ) ||
- (mContainerSiteP->RequestFocus(true, KeyboardFocus) == S_OK &&
- FocusSet(mOwnedFoci = FocusSet(mOwnedFoci | KeyboardFocus)) != EmptyFocusSet))
- {
- PLstrcpy(mMessage, "\pmouseDown");
- doInval = true;
- FireEvent(IID_IStandardEvents, DISPID_MOUSEDOWN, inEvent);
-
- // Was this soon enough after the last mouse up to be a double-click?
- if ((inEvent->when - mLastMouseUpTime) <= ::GetDblTime())
- {
- PLstrcpy(mMessage, "\pdoubleClick");
- FireEvent(IID_IStandardEvents, DISPID_DBLCLICK, inEvent);
- }
- }
- break;
-
- case MouseUp:
- if (mOwnedFoci & KeyboardFocus)
- {
- mLastMouseUpTime = inEvent->when;
- PLstrcpy(mMessage, "\pmouseUp");
- doInval = true;
- FireEvent(IID_IStandardEvents, DISPID_MOUSEUP, inEvent);
- }
- break;
- }
-
- // Invalidate the position rectangle so we'll get redrawn
- if (doInval)
- {
- InvalAllContexts();
- }
-
- return S_OK;
- }
-
-
- //
- // CEventSend::IControl::DoKey
- //
-
- STDMETHODIMP
- CEventSend::DoKey(KeyEventType inKeyET, Char8 inChar, PlatformEvent* inEvent)
- {
- Boolean doInval = false;
-
- switch (inKeyET)
- {
- case KeyDown:
- // if we have the focus, handle the key down
- if ( mOwnedFoci & KeyboardFocus )
- {
- PLstrcpy(mMessage, "\pkeyDown: ");
- // Display the key pressed in the message
- mMessage[0]++;
- mMessage[mMessage[0]] = inChar;
- doInval = true;
- FireEvent(IID_IStandardEvents, DISPID_KEYDOWN, inEvent);
- }
- break;
-
- case AutoKey:
- // if we have the focus, handle the key down
- if ( mOwnedFoci & KeyboardFocus )
- {
- PLstrcpy(mMessage, "\pautoKey: ");
- // Display the key pressed in the message
- mMessage[0]++;
- mMessage[mMessage[0]] = inChar;
- doInval = true;
- FireEvent(IID_IStandardEvents, DISPID_AUTOKEY, inEvent);
- }
- break;
-
- case KeyUp:
- // if we have the focus, handle the key up
- if ( mOwnedFoci & KeyboardFocus )
- {
- PLstrcpy(mMessage, "\pkeyUp: ");
- // Display the key pressed in the message
- mMessage[0]++;
- mMessage[mMessage[0]] = inChar;
- doInval = true;
- FireEvent(IID_IStandardEvents, DISPID_KEYUP, inEvent);
- }
- break;
- }
-
- // Invalidate the position rectangle so we'll get redrawn
- if (doInval)
- {
- InvalAllContexts();
- }
-
- return S_OK;
- }
-
-
- //
- // CEventSend:IControl:SetFocus
- //
-
- STDMETHODIMP
- CEventSend::SetFocus(FocusCommand inCommand, FocusSet inFocus)
- {
- DrawContext theContext = {BeginPortType};
- ErrorCode theResult = S_OK;
- FocusSet origOwnedFoci = mOwnedFoci;
-
- // a TakeNext or TakePrev if we don't have the focus, means take it
- if ((inCommand == TakeNextCommand || inCommand == TakePrevCommand) && !mOwnedFoci)
- {
- // if the container is offering us the one focus we want, take all of them
- if (inFocus & KeyboardFocus)
- mOwnedFoci = inFocus;
- else
- // otherwise, say no thanks
- theResult = E_FAIL;
- }
- // a TakeNext or a TakePrev on a control which doesn't embed and has the focus should fail
- else if (inCommand == TakeNextCommand || inCommand == TakePrevCommand)
- {
- theResult = E_FAIL;
- }
- // we're being asked/told to release our foci - always comply
- else // if (Spec == ReleaseRequest || Spec == ReleaseCommand)
- {
- if (inFocus & mOwnedFoci != inFocus)
- DebugStr("\pWhat are they doing asking to release foci we don't have?");
-
- mOwnedFoci = FocusSet(mOwnedFoci & ~inFocus); // really easy for us
- }
-
- // if the focus state of the keyboard changed
- if ((origOwnedFoci & KeyboardFocus) != (mOwnedFoci & KeyboardFocus))
- {
- InvalAllContexts();
- }
-
- return theResult;
- }
-
- // CEventSend::IPersistPropertyBag::Load
- //
-
- STDMETHODIMP
- CEventSend::Load(IPropertyBag* PropertyBag, IErrorLog* ErrorLog)
- {
- VARIANT v;
- Uint32 length;
-
- v.vt = VT_BSTR;
- v.bstrVal = NULL;
-
- // try to load in the property. if we can't get it, then leave
- // things at their default.
- //
- PropertyBag->Read("id", &v, ErrorLog);
- if (v.bstrVal)
- {
- length = *((Uint32*) v.bstrVal) ;
- if (mIdP)
- delete [] mIdP;
- mIdP = new char[length + 1];
- strcpy(mIdP, v.bstrVal + sizeof(Uint32));
- CoTaskMemFree(v.bstrVal);
- }
-
- return S_OK;
- }
-
-
-
-