home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / activexcontrol / basectl / framewrk / ctlhelp.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-05  |  8.9 KB  |  291 lines

  1. //=--------------------------------------------------------------------------=
  2. // CtlHelp.Cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995-1997 Microsoft Corporation.  All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // helper routines for our COleControl implementation
  13. //
  14.  
  15. #include "IPServer.H"
  16. #include "CtrlObj.H"
  17.  
  18. #include "CtlHelp.H"
  19. #include "Util.H"
  20. #include <windows.h>
  21.  
  22. // for ASSERT and FAIL
  23. //
  24. SZTHISFILE
  25.  
  26. //=--------------------------------------------------------------------------=
  27. // this is used by the window reflection code.
  28. //
  29. extern BYTE g_fRegisteredReflect;
  30. extern char g_szReflectClassName [];
  31.  
  32.  
  33. // define this here, since it's the only guid we really need to define in the
  34. // framework -- the user control defines all other interesting guids.
  35. //
  36. static const GUID IID_IControlPrv =
  37. { 0xd97180, 0xfcf7, 0x11ce, { 0xa0, 0x9e, 0x0, 0xaa, 0x0, 0x62, 0xbe, 0x57 } };
  38.  
  39.  
  40. // this table is used for copying data around, and persisting properties.
  41. // basically, it contains the size of a given data type
  42. //
  43. const BYTE g_rgcbDataTypeSize[] = {
  44.     0,                      // VT_EMPTY= 0,
  45.     0,                      // VT_NULL= 1,
  46.     sizeof(short),          // VT_I2= 2,
  47.     sizeof(long),           // VT_I4 = 3,
  48.     sizeof(float),          // VT_R4  = 4,
  49.     sizeof(double),         // VT_R8= 5,
  50.     sizeof(CURRENCY),       // VT_CY= 6,
  51.     sizeof(DATE),           // VT_DATE = 7,
  52.     sizeof(BSTR),           // VT_BSTR = 8,
  53.     sizeof(IDispatch *),    // VT_DISPATCH    = 9,
  54.     sizeof(SCODE),          // VT_ERROR    = 10,
  55.     sizeof(VARIANT_BOOL),   // VT_BOOL    = 11,
  56.     sizeof(VARIANT),        // VT_VARIANT= 12,
  57.     sizeof(IUnknown *),     // VT_UNKNOWN= 13,
  58. };
  59.  
  60. const BYTE g_rgcbPromotedDataTypeSize[] = {
  61.     0,                      // VT_EMPTY= 0,
  62.     0,                      // VT_NULL= 1,
  63.     sizeof(int ),           // VT_I2= 2,
  64.     sizeof(long),           // VT_I4 = 3,
  65.     sizeof(double),         // VT_R4  = 4,
  66.     sizeof(double),         // VT_R8= 5,
  67.     sizeof(CURRENCY),       // VT_CY= 6,
  68.     sizeof(DATE),           // VT_DATE = 7,
  69.     sizeof(BSTR),           // VT_BSTR = 8,
  70.     sizeof(IDispatch *),    // VT_DISPATCH    = 9,
  71.     sizeof(SCODE),          // VT_ERROR    = 10,
  72.     sizeof(int),            // VT_BOOL    = 11,
  73.     sizeof(VARIANT),        // VT_VARIANT= 12,
  74.     sizeof(IUnknown *),     // VT_UNKNOWN= 13,
  75. };
  76.  
  77. //=--------------------------------------------------------------------------=
  78. // _SpecialKeyState
  79. //=--------------------------------------------------------------------------=
  80. // returns a short with some information on which of the SHIFT, ALT, and CTRL
  81. // keys are set.
  82. //
  83. // Output:
  84. //    short        - bit 0 is shift, bit 1 is ctrl, bit 2 is ALT.
  85. //
  86. // Notes:
  87. //
  88. short _SpecialKeyState()
  89. {
  90.     // don't appear to be able to reduce number of calls to GetKeyState
  91.     //
  92.     BOOL bShift = (GetKeyState(VK_SHIFT) < 0);
  93.     BOOL bCtrl  = (GetKeyState(VK_CONTROL) < 0);
  94.     BOOL bAlt   = (GetKeyState(VK_MENU) < 0);
  95.  
  96.     return (short)(bShift + (bCtrl << 1) + (bAlt << 2));
  97. }
  98.  
  99.  
  100. //=--------------------------------------------------------------------------=
  101. // CopyAndAddRefObject
  102. //=--------------------------------------------------------------------------=
  103. // copies an object pointer, and then addref's the object.
  104. //
  105. // Parameters:
  106. //    void *        - [in] dest.
  107. //    const void *  - [in] src
  108. //    DWORD         - [in] size, ignored, since it's always 4
  109. //
  110. // Notes:
  111. //
  112. void WINAPI CopyAndAddRefObject
  113. (
  114.     void       *pDest,
  115.     const void *pSource,
  116.     DWORD       dwSize
  117. )
  118. {
  119.     ASSERT(pDest && pSource, "Bogus Pointer(s) passed into CopyAndAddRefObject!!!!");
  120.  
  121.     *((IUnknown **)pDest) = *((IUnknown **)pSource);
  122.     ADDREF_OBJECT(*((IUnknown **)pDest));
  123.  
  124.     return;
  125. }
  126.  
  127. //=--------------------------------------------------------------------------=
  128. // CopyOleVerb    [helper]
  129. //=--------------------------------------------------------------------------=
  130. // copies an OLEVERB structure.  used in CStandardEnum
  131. //
  132. // Parameters:
  133. //    void *        - [out] where to copy to
  134. //    const void *  - [in]  where to copy from
  135. //    DWORD         - [in]  bytes to copy
  136. //
  137. // Notes:
  138. //
  139. void WINAPI CopyOleVerb
  140. (
  141.     void       *pvDest,
  142.     const void *pvSrc,
  143.     DWORD       cbCopy
  144. )
  145. {
  146.     VERBINFO * pVerbDest = (VERBINFO *) pvDest;
  147.     const VERBINFO * pVerbSrc = (const VERBINFO *) pvSrc;
  148.  
  149.     *pVerbDest = *pVerbSrc;
  150.     ((OLEVERB *)pVerbDest)->lpszVerbName = OLESTRFROMRESID((WORD)((VERBINFO *)pvSrc)->idVerbName);
  151. }
  152.  
  153. //=--------------------------------------------------------------------------=
  154. // ControlFromUnknown    [helper, callable]
  155. //=--------------------------------------------------------------------------=
  156. // given an unknown, get the COleControl pointer for it.
  157. //
  158. // Parameters:
  159. //    IUnknown *        - [in]
  160. //
  161. // Output:
  162. //    HRESULT
  163. //
  164. // Notes:
  165. //
  166. COleControl *ControlFromUnknown
  167. (
  168.     IUnknown *pUnk
  169. )
  170. {
  171.     COleControl *pCtl = NULL;
  172.  
  173.     if (!pUnk) return NULL;
  174.     pUnk->QueryInterface(IID_IControlPrv, (void **)&pCtl);
  175.  
  176.     return pCtl;
  177. }
  178.  
  179. //=--------------------------------------------------------------------------=
  180. // CreateReflectWindow    [blech]
  181. //=--------------------------------------------------------------------------=
  182. // unfortunately, in certain cases, we have to create two windows, one of
  183. // which exists strictly to reflect messages on to the control.  Majorly
  184. // lame.  Fortunately, the number of hosts which require this is quite small.
  185. //
  186. // Parameters:
  187. //    BOOL        - [in] should it be created visible?
  188. //    HWND        - [in] parent window
  189. //    int         - [in] x pos
  190. //    int         - [in] y pos
  191. //    SIZEL *     - [in] size
  192. //
  193. // Output:
  194. //    HWND        - reflecting hwnd or NULL if it failed.
  195. //
  196. // Notes:
  197. //
  198. HWND CreateReflectWindow
  199. (
  200.     BOOL   fVisible,
  201.     HWND   hwndParent,
  202.     int    x,
  203.     int    y,
  204.     SIZEL *pSize
  205. )
  206. {
  207.     WNDCLASS wndclass;
  208.  
  209.     // first thing to do is register the window class.  crit sect this
  210.     // so we don't have to move it into the control
  211.     //
  212.     EnterCriticalSection(&g_CriticalSection);
  213.     if (!g_fRegisteredReflect) {
  214.  
  215.         memset(&wndclass, 0, sizeof(wndclass));
  216.         wndclass.lpfnWndProc = COleControl::ReflectWindowProc;
  217.         wndclass.hInstance   = g_hInstance;
  218.         wndclass.lpszClassName = g_szReflectClassName;
  219.  
  220.         if (!RegisterClass(&wndclass)) {
  221.             FAIL("Couldn't Register Parking Window Class!");
  222.             LeaveCriticalSection(&g_CriticalSection);
  223.             return NULL;
  224.         }
  225.         g_fRegisteredReflect = TRUE;
  226.     }
  227.  
  228.     LeaveCriticalSection(&g_CriticalSection);
  229.  
  230.     // go and create the window.
  231.     //
  232.     return CreateWindowEx(0, g_szReflectClassName, NULL,
  233.                           WS_CHILD | WS_CLIPSIBLINGS |((fVisible) ? WS_VISIBLE : 0),
  234.                           x, y, pSize->cx, pSize->cy,
  235.                           hwndParent,
  236.                           NULL, g_hInstance, NULL);
  237. }
  238.  
  239. //=--------------------------------------------------------------------------=
  240. // in case the user doesn't want our default window proc, we support
  241. // letting them specify one themselves. this is defined in their main ipserver
  242. // file.
  243. //
  244. extern WNDPROC g_ParkingWindowProc;
  245.  
  246. //=--------------------------------------------------------------------------=
  247. // GetParkingWindow
  248. //=--------------------------------------------------------------------------=
  249. // creates the global parking window that we'll use to parent things, or
  250. // returns the already existing one
  251. //
  252. // Output:
  253. //    HWND                - our parking window
  254. //
  255. // Notes:
  256. //
  257. HWND GetParkingWindow
  258. (
  259.     void
  260. )
  261. {
  262.     WNDCLASS wndclass;
  263.  
  264.     // crit sect this creation for apartment threading support.
  265.     //
  266.     EnterCriticalSection(&g_CriticalSection);
  267.     if (g_hwndParking)
  268.         goto CleanUp;
  269.  
  270.     ZeroMemory(&wndclass, sizeof(wndclass));
  271.     wndclass.lpfnWndProc = (g_ParkingWindowProc) ? g_ParkingWindowProc : DefWindowProc;
  272.     wndclass.hInstance   = g_hInstance;
  273.     wndclass.lpszClassName = "CtlFrameWork_Parking";
  274.  
  275.     if (!RegisterClass(&wndclass)) {
  276.         FAIL("Couldn't Register Parking Window Class!");
  277.         goto CleanUp;
  278.     }
  279.  
  280.     g_hwndParking = CreateWindow("CtlFrameWork_Parking", NULL, WS_POPUP, 0, 0, 0, 0, NULL, NULL, g_hInstance, NULL);
  281.     if (g_hwndParking != NULL)
  282.        ++g_cLocks;
  283.  
  284.     ASSERT(g_hwndParking, "Couldn't Create Global parking window!!");
  285.  
  286.  
  287.   CleanUp:
  288.     LeaveCriticalSection(&g_CriticalSection);
  289.     return g_hwndParking;
  290. }
  291.