You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
259 lines
7.9 KiB
259 lines
7.9 KiB
//=--------------------------------------------------------------------------=
|
|
// 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);
|
|
}
|