|
|
//=--------------------------------------------------------------------------=
// CtlHelper.Cpp
//=--------------------------------------------------------------------------=
// Copyright 1995 Microsoft Corporation. All Rights Reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//=--------------------------------------------------------------------------=
//
// helper routines for our COleControl implementation
//
#include "pch.h"
#include "CtrlObj.H"
#include "CtlHelp.H"
#include <windowsx.h>
// for ASSERT and FAIL
//
SZTHISFILE
//=--------------------------------------------------------------------------=
// this is used by the window reflection code.
//
extern BYTE g_fRegisteredReflect; extern const char g_szReflectClassName [];
// define this here, since it's the only guid we really need to define in the
// framework -- the user control defines all other interesting guids.
//
static const GUID IID_IControlPrv = { 0xd97180, 0xfcf7, 0x11ce, { 0xa0, 0x9e, 0x0, 0xaa, 0x0, 0x62, 0xbe, 0x57 } };
//=--------------------------------------------------------------------------=
// _SpecialKeyState
//=--------------------------------------------------------------------------=
// returns a short with some information on which of the SHIFT, ALT, and CTRL
// keys are set.
//
// Output:
// short - bit 0 is shift, bit 1 is ctrl, bit 2 is ALT.
//
// Notes:
//
short _SpecialKeyState() { // don't appear to be able to reduce number of calls to GetKeyState
//
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)); }
//=--------------------------------------------------------------------------=
// CopyOleVerb [helper]
//=--------------------------------------------------------------------------=
// copies an OLEVERB structure. used in CStandardEnum
//
// Parameters:
// void * - [out] where to copy to
// const void * - [in] where to copy from
// DWORD - [in] bytes to copy
//
// Notes:
//
void WINAPI CopyOleVerb ( void *pvDest, const void *pvSrc, DWORD cbCopy ) { VERBINFO * pVerbDest = (VERBINFO *) pvDest; const VERBINFO * pVerbSrc = (const VERBINFO *) pvSrc;
*pVerbDest = *pVerbSrc; ((OLEVERB *)pVerbDest)->lpszVerbName = OLESTRFROMRESID((WORD)((VERBINFO *)pvSrc)->idVerbName); }
//=--------------------------------------------------------------------------=
// ControlFromUnknown [helper, callable]
//=--------------------------------------------------------------------------=
// given an unknown, get the COleControl pointer for it.
//
// Parameters:
// IUnknown * - [in]
//
// Output:
// HRESULT
//
// Notes:
//
COleControl *ControlFromUnknown ( IUnknown *pUnk ) { HRESULT hr; IControlPrv *pControlPrv = NULL; COleControl *pCtl = NULL;
if (!pUnk) return NULL; hr = pUnk->QueryInterface(IID_IControlPrv, (void **)&pControlPrv); ASSERT(SUCCEEDED(hr), "Failed to get IControlPrv interface");
hr = pControlPrv->GetControl(&pCtl); ASSERT(SUCCEEDED(hr), "Failed to get COleControl pointer"); QUICK_RELEASE(pControlPrv); return pCtl; }
//=--------------------------------------------------------------------------=
// CreateReflectWindow [blech]
//=--------------------------------------------------------------------------=
// unfortunately, in certain cases, we have to create two windows, one of
// which exists strictly to reflect messages on to the control. Majorly
// lame. Fortunately, the number of hosts which require this is quite small.
//
// Parameters:
// BOOL - [in] should it be created visible?
// HWND - [in] parent window
// int - [in] x pos
// int - [in] y pos
// SIZEL * - [in] size
//
// Output:
// HWND - reflecting hwnd or NULL if it failed.
//
// Notes:
//
HWND CreateReflectWindow ( BOOL fVisible, HWND hwndParent, int x, int y, SIZEL *pSize ) { WNDCLASS wndclass;
// first thing to do is register the window class. crit sect this
// so we don't have to move it into the control
//
ENTERCRITICALSECTION1(&g_CriticalSection); if (!g_fRegisteredReflect) {
memset(&wndclass, 0, sizeof(wndclass)); wndclass.lpfnWndProc = COleControl::ReflectWindowProc; wndclass.hInstance = g_hInstance; wndclass.lpszClassName = g_szReflectClassName;
if (!RegisterClass(&wndclass)) { FAIL("Couldn't Register Parking Window Class!"); LEAVECRITICALSECTION1(&g_CriticalSection); return NULL; } g_fRegisteredReflect = TRUE; }
LEAVECRITICALSECTION1(&g_CriticalSection);
// go and create the window.
//
return CreateWindowEx(0, g_szReflectClassName, NULL, WS_CHILD | WS_CLIPSIBLINGS |((fVisible) ? WS_VISIBLE : 0), x, y, pSize->cx, pSize->cy, hwndParent, NULL, g_hInstance, NULL); }
//=--------------------------------------------------------------------------=
// in case the user doesn't want our default window proc, we support
// letting them specify one themselves. this is defined in their main ipserver
// file.
//
// Note: As of VB6 we added ParkingWindowProc to the framework.
// The ParkingWindowProc supports message reflection which is normally
// the code you add to your implementation of ParkingWindowProc.
// In most cases you can probably set this to NULL in your control's
// implementation
//
extern WNDPROC g_ParkingWindowProc;
//=--------------------------------------------------------------------------=
// GetParkingWindow
//=--------------------------------------------------------------------------=
// creates the global parking window that we'll use to parent things, or
// returns the already existing one
//
// Output:
// HWND - our parking window
//
// Notes:
//
HWND GetParkingWindow ( void ) { WNDCLASS wndclass;
// crit sect this creation for apartment threading support.
//
ENTERCRITICALSECTION1(&g_CriticalSection); if (g_hwndParking) goto CleanUp;
ZeroMemory(&wndclass, sizeof(wndclass)); wndclass.lpfnWndProc = (g_ParkingWindowProc) ? g_ParkingWindowProc : COleControl::ParkingWindowProc; wndclass.hInstance = g_hInstance; wndclass.lpszClassName = "CtlFrameWork_Parking";
if (!RegisterClass(&wndclass)) { FAIL("Couldn't Register Parking Window Class!"); goto CleanUp; }
g_hwndParking = CreateWindow("CtlFrameWork_Parking", NULL, WS_POPUP, 0, 0, 0, 0, NULL, NULL, g_hInstance, NULL); ASSERT(g_hwndParking, "Couldn't Create Global parking window!!");
CleanUp: LEAVECRITICALSECTION1(&g_CriticalSection); return g_hwndParking; }
//=--------------------------------------------------------------------------=
// ParkingWindowProc
//=--------------------------------------------------------------------------=
// Provides default processing for the parking window. Since your control
// may be parented by the parking window, we provide message reflection.
//
LRESULT CALLBACK COleControl::ParkingWindowProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { LRESULT lResult;
// If the message is reflected then return the result of the OCM_ message
//
if (ReflectOcmMessage(hwnd, msg, wParam, lParam, &lResult)) return lResult; return DefWindowProc(hwnd, msg, wParam, lParam); }
|