home *** CD-ROM | disk | FTP | other *** search
/ ...taking it to the Macs! / ...taking it to the Macs!.iso / Extras / ActiveX Mac SDK / ActiveX SDK / Sample Controls / HLink / CHLinkControl.cpp next >
Encoding:
Text File  |  1996-12-16  |  7.3 KB  |  344 lines  |  [TEXT/CWIE]

  1. // =================================================================================
  2. //
  3. //    CHLinkControl.cpp                ©1996 Microsoft Corporation All rights reserved.
  4. //
  5. // =================================================================================
  6.  
  7. #include "ocheaders.h"
  8. #include "CCFragResource.h"
  9. #include "CHLinkControl.h"
  10.  
  11.  
  12. const Int16    OvalSize = 20;
  13. const Int16 FingerCursorResID = 128;
  14.  
  15. #pragma mark === CHLinkControl::Construction & Destruction ===
  16.  
  17. //
  18. //  CHLinkControl::CHLinkControl
  19. //
  20.  
  21. CHLinkControl::CHLinkControl(void) : CBaseControl()
  22. {
  23.     mHLinkP = nil;
  24.     mTargetURL[0] = 0;
  25.     mLinkType = BeginHLinkNavigate;
  26.     mIDP = nil;
  27.  
  28.     // Get the finger cursor
  29.     {
  30.         CCFragResource    ResourceSetter;    // Sets us to the control's resource file
  31.  
  32.         mFingerCursor = GetCursor(FingerCursorResID);
  33.         if ( mFingerCursor )
  34.             DetachResource((Handle) mFingerCursor);
  35.     }
  36.     // Resource file is reset when ResourceSetter goes out of scope
  37. }
  38.  
  39. //
  40. //  CHLinkControl::~CHLinkControl
  41. //
  42.  
  43. CHLinkControl::~CHLinkControl(void)
  44. {
  45.     if ( mHLinkP )
  46.         mHLinkP->Release();
  47.         
  48.     if ( mFingerCursor )
  49.         DisposeHandle((Handle) mFingerCursor);
  50.  
  51.     if ( mIDP )
  52.         delete [] mIDP;
  53. }
  54.  
  55. #pragma mark === CHLinkControl::IObjectWithSite ===
  56.  
  57. //=--------------------------------------------------------------------------=
  58. //  CHLinkControl::IObjectWithSite::SetSite
  59. //=--------------------------------------------------------------------------=
  60. // informs the control of it's client site display
  61. // location within it's container
  62. //
  63. STDMETHODIMP
  64. CHLinkControl::SetSite(IUnknown* inClientSite)
  65. {
  66.     CBaseControl::SetSite(inClientSite);
  67.     
  68.     // Get the hyperlink interface
  69.     if ( inClientSite )
  70.     {
  71.         if ( mHLinkP )
  72.             mHLinkP->Release();
  73.          mUnkOuterP->QueryInterface(IID_IHLinkBasic, &mHLinkP);
  74.      }
  75.          
  76.      return S_OK;
  77.         
  78. }
  79.  
  80.  
  81. #pragma mark === CHLinkControl::IControl ===
  82.  
  83. //
  84. //  CHLinkControl::IControl::Draw
  85. //
  86.  
  87. STDMETHODIMP
  88. CHLinkControl::Draw( DrawContext* inContext)
  89. {
  90.     Str255    Name;
  91.     Int16     NameWidth, NameHeight, ButtonWidth, ButtonHeight;
  92.     Rect    ButtonRect = inContext->Location;
  93.     
  94.     // Position the Button rect
  95.     InsetRect(&ButtonRect, 5, 5);
  96.     
  97.     // Erase the area
  98.     EraseRoundRect(&ButtonRect, OvalSize, OvalSize);
  99.  
  100.     // Frame the button
  101.     PenSize(2, 2);
  102.     FrameRoundRect(&ButtonRect, OvalSize, OvalSize);
  103.     PenSize(1, 1);
  104.     
  105.     // Center the text
  106.     ::TextFont(applFont);
  107.     ::TextFace(0);
  108.     if ( ButtonEnabled() )
  109.         ::TextMode(srcCopy);
  110.     else
  111.         ::TextMode(grayishTextOr);
  112.     ::TextSize(12);
  113.     GetID(255, (Char8*)Name+1);
  114.     *Name = strlen((Char8*)Name+1);
  115.     NameWidth = ::StringWidth(Name);
  116.     NameHeight = 12;
  117.     ButtonWidth = ButtonRect.right - ButtonRect.left;
  118.     ButtonHeight = ButtonRect.bottom - ButtonRect.top;
  119.     ::MoveTo(ButtonRect.left+ ((ButtonWidth - NameWidth) / 2), 
  120.             ButtonRect.top + ((ButtonHeight - NameHeight) / 2 + NameHeight));
  121.     
  122.     // Draw the name
  123.     ::DrawString(Name);
  124.     
  125.     return S_OK;
  126. }
  127.  
  128.  
  129. //
  130. //  CHLinkControl::IControl::GetID
  131. //
  132.  
  133. STDMETHODIMP
  134. CHLinkControl::GetID(Int32 inBufferSize, Char8* outID)
  135. {
  136.     if (mIDP)
  137.     {
  138.         Int16    IDLen = strlen(mIDP);
  139.  
  140.         if (IDLen > --inBufferSize)
  141.             IDLen = inBufferSize;
  142.         ::BlockMove(mIDP, outID, IDLen);
  143.         *(outID + IDLen) = '\0';
  144.     }
  145.     else
  146.         return CBaseControl::GetID(inBufferSize, outID);
  147.  
  148.     return S_OK;
  149. }
  150.  
  151.  
  152. //
  153. //  CHLinkControl::IControl::DoMouse
  154. //
  155. STDMETHODIMP
  156. CHLinkControl::DoMouse(MouseEventType inMouseET, PlatformEvent* inEvent)
  157. {
  158. #pragma unused (inEvent)
  159.  
  160.     if ( ButtonEnabled() )
  161.     {
  162.         switch (inMouseET) 
  163.         {
  164.             case MouseEnter:
  165.                 SetCursor(*mFingerCursor);
  166.                 break;
  167.             
  168.             case MouseLeave:
  169.                 // Hope the app sets it back to its cursor
  170.                 break;
  171.                 
  172.             case MouseDown:
  173.             {
  174.                 DrawContext Context = {BeginPortType};
  175.                 
  176.                 if ( mContainerSiteP->AcquireContext(mActiveContext->GetContextID(), &Context) == S_OK )
  177.                 {
  178.                     Rect    ButtonRect = Context.Location;
  179.                     
  180.                     // Position the Button rect
  181.                     ::InsetRect(&ButtonRect, 5, 5);
  182.                     
  183.                     // Do the button behavior
  184.                     ::InvertRoundRect(&ButtonRect, OvalSize, OvalSize);
  185.                     while (StillDown()) ;
  186.                     ::InvertRoundRect(&ButtonRect, OvalSize, OvalSize);
  187.                     
  188.                     // Release the context
  189.                     mContainerSiteP->ReleaseContext(&Context);
  190.                 }
  191.                 
  192.                 break;
  193.             }
  194.                 
  195.             case MouseUp:
  196.                   switch (mLinkType)
  197.                   {
  198.                       case NavigateURL:
  199.                           mHLinkP->GotoURL(TargetCurrent, (char*)mTargetURL);
  200.                           break;
  201.  
  202.                       case NavigateBack:
  203.                           mHLinkP->GoBack();
  204.                           break;
  205.  
  206.                       case NavigateForward:
  207.                           mHLinkP->GoForward();
  208.                           break;
  209.                   }
  210.                   break;
  211.         }
  212.     }
  213.     else if ( inMouseET == MouseDown )
  214.         ::SysBeep(60);
  215.  
  216.     return S_OK;
  217. }
  218.  
  219. //
  220. //  CHLinkControl::ButtonEnabled
  221. //
  222. Boolean CHLinkControl::ButtonEnabled(void)
  223. {
  224.     Boolean Enabled = false;
  225.     
  226.     if ( mHLinkP )
  227.     {
  228.         switch (mLinkType)
  229.         {
  230.             case NavigateURL:
  231.                 Enabled = ( strlen((char*) mTargetURL) > 0 );
  232.                 break;
  233.                 
  234.             case NavigateBack:
  235.                 Enabled = ( mHLinkP->CanGoBack() == S_OK );
  236.                 break;
  237.                 
  238.             case NavigateForward:
  239.                 Enabled = ( mHLinkP->CanGoForward() == S_OK );
  240.                 break;
  241.         }
  242.     }
  243.     
  244.     
  245.     return Enabled;
  246.         
  247. }
  248.  
  249.  
  250. #pragma mark === CHLinkControl::IPersistPropertyBag ===
  251.  
  252. //
  253. //  CHLinkControl::IPersistPropertyBag::Load
  254. //
  255.  
  256. STDMETHODIMP
  257. CHLinkControl::Load(IPropertyBag* PropertyBag, IErrorLog* ErrorLog)
  258. {
  259.  
  260.     LoadTextState(PropertyBag, ErrorLog);
  261.     
  262.     return S_OK;
  263. }
  264.  
  265. //=--------------------------------------------------------------------------=
  266. // CHLinkControl::LoadTextState
  267. //=--------------------------------------------------------------------------=
  268. // load in our text state for this control.
  269. //
  270. // Parameters:
  271. //    IPropertyBag *        - [in] property bag to read from
  272. //    IErrorLog *           - [in] errorlog object to use with proeprty bag
  273. //
  274. // Output:
  275. //    ErrorCode
  276. //
  277. STDMETHODIMP CHLinkControl::LoadTextState(IPropertyBag *PropertyBag, IErrorLog *ErrorLog)
  278. {
  279.     VARIANT        v;
  280.     Uint32        length;
  281.  
  282. //    VariantInit(&v);
  283.  
  284.     v.vt = VT_BSTR;
  285.     v.bstrVal = NULL;
  286.  
  287.     // try to load in the property.  if we can't get it, then leave
  288.     // things at their default.
  289.     //
  290.     PropertyBag->Read("target", &v, ErrorLog);
  291.     if (v.bstrVal)
  292.     {
  293.         length = *((Uint32*) v.bstrVal) ;
  294.         strcpy((Char8*)mTargetURL, v.bstrVal + sizeof(Uint32));
  295.         CoTaskMemFree(v.bstrVal);
  296. //        VariantInit(&v);
  297.     }
  298.  
  299.     v.vt = VT_BSTR;
  300.     v.bstrVal = NULL;
  301.  
  302.     // try to load in the property.  if we can't get it, then leave
  303.     // things at their default.
  304.     //
  305.     PropertyBag->Read("id", &v, ErrorLog);
  306.     if (v.bstrVal)
  307.     {
  308.         length = *((Uint32*) v.bstrVal) ;
  309.         if (mIDP)
  310.             delete [] mIDP;
  311.         mIDP = new char[length + 1];
  312.         strcpy((Char8*) mIDP, v.bstrVal + sizeof(Uint32));
  313.         CoTaskMemFree(v.bstrVal);
  314. //        VariantInit(&v);
  315.     }
  316.  
  317.     v.vt = VT_BSTR;
  318.     v.bstrVal = NULL;
  319.  
  320.     // try to load in the property.  if we can't get it, then leave
  321.     // things at their default.
  322.     //
  323.     PropertyBag->Read("linktype", &v, ErrorLog);
  324.     if (v.bstrVal)
  325.     {
  326.         char LinkTypeStr[32];
  327.         
  328.         length = *((Uint32*) v.bstrVal) ;
  329.         strcpy((Char8*) LinkTypeStr, v.bstrVal + sizeof(Uint32));
  330.         if ( strcmp(LinkTypeStr, "goto") == 0 )
  331.             mLinkType = NavigateURL;
  332.         else if ( strcmp(LinkTypeStr, "goback") == 0 )
  333.             mLinkType = NavigateBack;
  334.         else if ( strcmp(LinkTypeStr, "goforward") == 0 )
  335.             mLinkType = NavigateForward;
  336.             
  337.         CoTaskMemFree(v.bstrVal);
  338. //        VariantInit(&v);
  339.     }
  340.  
  341.     return S_OK;
  342. }
  343.  
  344.