|
|
/***************************************************************************\
* * File: ApiStubs.cpp * * Description: * ApiStubs.cpp exposes all public DirectUser API's in the Win32 world. * * * History: * 1/18/2000: JStall: Created * * Copyright (C) 2000 by Microsoft Corporation. All rights reserved. * \***************************************************************************/
#include "stdafx.h"
#include "WinAPI.h"
#include "DwpEx.h"
#define DUSER_API
#pragma warning(disable: 4296) // expression is always false
//
// Undefine the macros declared in ObjectAPI because they will be redefined
// here for the WinAPI handle-based API's.
//
#undef BEGIN_API
#undef END_API
#undef BEGIN_API_NOLOCK
#undef END_API_NOLOCK
#undef BEGIN_API_NOCONTEXT
#undef END_API_NOCONTEXT
#undef CHECK_MODIFY
#undef VALIDATE_GADGETCONTEXT
#undef VALIDATE_VALUE
#undef VALIDATE_HWND
#undef VALIDATE_REGION
#undef VALIDATE_OBJECT
#undef VALIDATE_EVENTGADGET
#undef VALIDATE_EVENTGADGET_NOCONTEXT
#undef VALIDATE_VISUAL
#undef VALIDATE_ROOTGADGET
#undef VALIDATE_VISUAL_OR_NULL
#undef VALIDATE_TRANSITION
#undef VALIDATE_FLAGS
#undef VALIDATE_RANGE
#undef VALIDATE_CODE_PTR
#undef VALIDATE_CODE_PTR_OR_NULL
#undef VALIDATE_READ_PTR
#undef VALIDATE_READ_PTR_
#undef VALIDATE_READ_PTR_OR_NULL_
#undef VALIDATE_READ_STRUCT
#undef VALIDATE_WRITE_PTR
#undef VALIDATE_WRITE_PTR_
#undef VALIDATE_WRITE_PTR_OR_NULL_
#undef VALIDATE_WRITE_STRUCT
#undef VALIDATE_STRING_PTR
#undef VALIDATE_STRINGA_PTR
#undef VALIDATE_STRINGW_PTR
//
// SET_RETURN is a convenient macro that converts from DirectUser error
// conditions and sets up the return value.
//
// NOTE: This MUST be a macro (and not an inline function) because we CANNOT
// evaluate success unless hr was actually successful. Unfortunately with
// function calls, success would need to be evaluated to call the function.
//
#define SET_RETURN(hr, success) \
do { \ if (SUCCEEDED(hr)) { \ retval = success; \ } else { \ SetError(hr); \ } \ } while (0) \
template <class T> inline void SetError(T dwErr) { SetLastError((DWORD) dwErr); }
//
// API Entry / Exit setup rountines
//
#define BEGIN_RECV(type, value, defermsg) \
type retval = value; \ type errret = value; \ UNREFERENCED_PARAMETER(errret); \ \ if (!IsInitContext()) { \ PromptInvalid("Must initialize Context before using thread"); \ SetError(DU_E_NOCONTEXT); \ goto rawErrorExit; \ } \ \ { \ ContextLock cl; \ if (!cl.LockNL(defermsg)) { \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \ Context * pctxThread = cl.pctx; \ AssertInstance(pctxThread); \ UNREFERENCED_PARAMETER(pctxThread); \
#define END_RECV() \
goto ErrorExit; \ ErrorExit: \ /* Unlocks the Context here */ \ ; \ } \ rawErrorExit: \ return retval;
#define BEGIN_RECV_NOLOCK(type, value) \
type retval = value; \ type errret = value; \ UNREFERENCED_PARAMETER(errret); \ \ if (!IsInitContext()) { \ PromptInvalid("Must initialize Context before using thread"); \ SetError(DU_E_NOCONTEXT); \ goto rawErrorExit; \ } \ \ { \ Context * pctxThread = ::GetContext(); \ AssertInstance(pctxThread); \
#define END_RECV_NOLOCK() \
goto ErrorExit; \ ErrorExit: \ ; \ } \ rawErrorExit: \ return retval;
#define BEGIN_RECV_NOCONTEXT(type, value) \
type retval = value; \ type errret = value; \ UNREFERENCED_PARAMETER(errret); \
#define END_RECV_NOCONTEXT() \
goto ErrorExit; \ ErrorExit: \ return retval;
#define CHECK_MODIFY() \
if (pctxThread->IsReadOnly()) { \ PromptInvalid("Can not call modifying function while in read-only state / callback"); \ SetError(DU_E_READONLYCONTEXT); \ goto ErrorExit; \ } \
//
// Individual parameter validation rountines
//
#define VALIDATE_GADGETCONTEXT(gad) \
{ \ Context * pctxGad = (p##gad)->GetContext(); \ if (pctxThread != pctxGad) { \ PromptInvalid("Must use Gadget inside correct Context"); \ SetError(DU_E_INVALIDCONTEXT); \ goto ErrorExit; \ } \ }
#define VALIDATE_VALUE(x, v) \
if (x != v) { \ SetError(E_INVALIDARG); \ goto ErrorExit; \ }
#define VALIDATE_HWND(wnd) \
if ((h##wnd == NULL) || (!IsWindow(h##wnd))) { \ PromptInvalid("Handle is not a valid Window"); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ }
#define VALIDATE_REGION(rgn) \
if (h##rgn == NULL) { \ PromptInvalid("Handle is not a valid region"); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ }
#define VALIDATE_OBJECT(obj) \
{ \ p##obj = BaseObject::ValidateHandle(h##obj); \ if (p##obj == NULL) { \ PromptInvalid("Handle is not a valid object"); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \ }
#define VALIDATE_EVENTGADGET(gad) \
{ \ p##gad = ValidateBaseGadget(h##gad); \ if (p##gad == NULL) { \ PromptInvalid("Handle is not a valid Gadget"); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \ VALIDATE_GADGETCONTEXT(gad) \ }
#define VALIDATE_EVENTGADGET_NOCONTEXT(gad) \
{ \ p##gad = ValidateBaseGadget(h##gad); \ if (p##gad == NULL) { \ PromptInvalid("Handle is not a valid Gadget"); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \ }
#define VALIDATE_VISUAL(gad) \
{ \ p##gad = ValidateVisual(h##gad); \ if (p##gad == NULL) { \ PromptInvalid("Handle is not a valid Gadget"); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \ VALIDATE_GADGETCONTEXT(gad) \ }
#define VALIDATE_ROOTGADGET(gad) \
{ \ { \ DuVisual * pgadTemp = ValidateVisual(h##gad); \ if (pgadTemp == NULL) { \ PromptInvalid("Handle is not a valid Gadget"); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \ if (!pgadTemp->IsRoot()) { \ goto ErrorExit; \ } \ VALIDATE_GADGETCONTEXT(gadTemp) \ p##gad = (DuRootGadget *) pgadTemp; \ } \ }
#define VALIDATE_VISUAL_OR_NULL(gad) \
{ \ if (h##gad == NULL) { \ p##gad = NULL; \ } else { \ p##gad = ValidateVisual(h##gad); \ if (p##gad == NULL) { \ PromptInvalid("Handle is not a valid Gadget"); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \ VALIDATE_GADGETCONTEXT(gad) \ } \ }
#define VALIDATE_TRANSITION(trx) \
{ \ BaseObject * pbase##trx = BaseObject::ValidateHandle(h##trx); \ p##trx = CastTransition(pbase##trx); \ if (p##trx == NULL) { \ PromptInvalid("Handle is not a valid Transition"); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \ }
#define VALIDATE_FLAGS(f, m) \
if ((f & m) != f) { \ PromptInvalid("Specified flags are invalid"); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ }
#define VALIDATE_RANGE(i, a, b) \
if (((i) < (a)) || ((i) > (b))) { \ PromptInvalid("Value is outside expected range"); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \
#define VALIDATE_CODE_PTR(p) \
if ((p == NULL) || IsBadCode(p)) { \ PromptInvalid("Bad code pointer: " STRINGIZE(p)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \
#define VALIDATE_CODE_PTR_OR_NULL(p) \
if ((p != NULL) && IsBadCode((FARPROC) p)) { \ PromptInvalid("Bad code pointer: " STRINGIZE(p)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \
#define VALIDATE_READ_PTR(p) \
if ((p == NULL) || IsBadRead(p, sizeof(char *))) { \ PromptInvalid("Bad read pointer: " STRINGIZE(p)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \
#define VALIDATE_READ_PTR_(p, b) \
if ((p == NULL) || IsBadRead(p, b)) { \ PromptInvalid("Bad read pointer: " STRINGIZE(p)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \
#define VALIDATE_READ_PTR_OR_NULL_(p, b) \
if ((p != NULL) && IsBadRead(p, b)) { \ PromptInvalid("Bad read pointer: " STRINGIZE(p)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \
#define VALIDATE_READ_STRUCT(p, s) \
if ((p == NULL) || IsBadRead(p, sizeof(s))) { \ PromptInvalid("Bad read pointer: " STRINGIZE(p)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \ if (p->cbSize != sizeof(s)) { \ PromptInvalid("Structure is not expected size for " STRINGIZE(s)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } #define VALIDATE_WRITE_PTR(p) \
if ((p == NULL) || IsBadWrite(p, sizeof(char *))) { \ PromptInvalid("Bad write pointer: " STRINGIZE(p)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \
#define VALIDATE_WRITE_PTR_(p, b) \
if ((p == NULL) || IsBadWrite(p, b)) { \ PromptInvalid("Bad write pointer: " STRINGIZE(p)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \
#define VALIDATE_WRITE_PTR_OR_NULL_(p, b) \
if ((p != NULL) && IsBadWrite(p, b)) { \ PromptInvalid("Bad write pointer: " STRINGIZE(p)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \
#define VALIDATE_WRITE_STRUCT(p, s) \
if ((p == NULL) || IsBadWrite(p, sizeof(s))) { \ PromptInvalid("Bad write pointer: " STRINGIZE(p)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \ if (p->cbSize != sizeof(s)) { \ PromptInvalid("Structure is not expected size for " STRINGIZE(s)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } #define VALIDATE_STRING_PTR(p, cch) \
if ((p == NULL) || IsBadString(p, cch)) { \ PromptInvalid("Bad string pointer: " STRINGIZE(p)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \
#define VALIDATE_STRINGA_PTR(p, cch) \
if ((p == NULL) || IsBadStringA(p, cch)) { \ PromptInvalid("Bad string pointer: " STRINGIZE(p)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \
#define VALIDATE_STRINGW_PTR(p, cch) \
if ((p == NULL) || IsBadStringW(p, cch)) { \ PromptInvalid("Bad string pointer: " STRINGIZE(p)); \ SetError(E_INVALIDARG); \ goto ErrorExit; \ } \
/***************************************************************************\
***************************************************************************** * * DirectUser CORE API * * InitGadgets() initializes a DirectUser Context. The Context is valid in * the Thread until it is explicitely destroyed with ::DeleteHandle() or the * thread exits. * * NOTE: It is VERY important that the first time this function is called is * NOT in DllMain() because we need to initialize the SRT. DllMain() * serializes access across all threads, so we will deadlock. After the first * Context is successfully created, additional Contexts can be created inside * DllMain(). * * <package name="Core"/> * ***************************************************************************** \***************************************************************************/
DUSER_API HDCONTEXT WINAPI InitGadgets( IN INITGADGET * pInit) { Context * pctxNew; HRESULT hr;
BEGIN_RECV_NOCONTEXT(HDCONTEXT, NULL); VALIDATE_READ_STRUCT(pInit, INITGADGET); VALIDATE_RANGE(pInit->nThreadMode, IGTM_MIN, IGTM_MAX); VALIDATE_RANGE(pInit->nMsgMode, IGMM_MIN, IGMM_MAX); VALIDATE_RANGE(pInit->nPerfMode, IGPM_MIN, IGPM_MAX);
hr = ResourceManager::InitContextNL(pInit, FALSE, &pctxNew); SET_RETURN(hr, (HDCONTEXT) GetHandle(pctxNew));
END_RECV_NOCONTEXT(); }
/***************************************************************************\
* * InitGadgetComponent (API) * * InitGadgetComponent() initializes optional DirectUser/Gadget components * that are not initialized by default. It is usually best to call this * function separately for each optional component to track individual * failures when initializing. * * <return type="BOOL"> Components were successfully initialized.</> * <see type="function"> CreateTransition</> * <see type="function"> UninitializeGadgetComponent</> * \***************************************************************************/ DUSER_API BOOL WINAPI InitGadgetComponent( IN UINT nOptionalComponent) // Optional component ID
{ HRESULT hr;
//
// InitComponentNL() doesn't actually synchronize on a Context, but needs
// a context to be initialized so that the threading model is determined.
//
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_RANGE(nOptionalComponent, IGC_MIN, IGC_MAX); CHECK_MODIFY();
hr = ResourceManager::InitComponentNL(nOptionalComponent); SET_RETURN(hr, TRUE);
END_RECV(); }
/***************************************************************************\
* * UninitGadgetComponent (API) * * UninitGadgetComponent() shuts down and cleans up optional DirectUser/Gadget * components that were previously initialized. * * <return type="BOOL"> Components were successfully uninitialized.</> * <see type="function"> InitGadgetComponent</> * \***************************************************************************/ DUSER_API BOOL WINAPI UninitGadgetComponent( IN UINT nOptionalComponent) // Optional component
{ HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_RANGE(nOptionalComponent, IGC_MIN, IGC_MAX); CHECK_MODIFY();
hr = ResourceManager::UninitComponentNL(nOptionalComponent); SET_RETURN(hr, TRUE);
END_RECV(); }
/***************************************************************************\
* * DeleteHandle (API) * * DeleteHandle() deletes any DirectUser handle by destroying the object and * cleaning up associated resources. After calling, the specified handle is * no longer valid. It may be used again later by another object. * * It is very important that only valid handles are given to ::DeleteHandle(). * Passing invalid handles (including previously deleted handles) will crash * DirectUser. * * <return type="BOOL"> Object was successfully deleted.</> * <see type="function"> CreateGadget</> * <see type="function"> CreateTransition</> * <see type="function"> CreateAction</> * \***************************************************************************/
DUSER_API BOOL WINAPI DeleteHandle( IN HANDLE h) // Handle to delete
{ BEGIN_RECV_NOLOCK(BOOL, FALSE); BaseObject * pobj = BaseObject::ValidateHandle(h); if (pobj != NULL) { if (pobj->GetHandleType() == htContext) { //
// When destroying a Context, we can't lock it or it won't get
// destroyed. This is okay since the ResourceManager serialize
// the requests when it locks the thread-list.
//
pobj->xwDeleteHandle(); retval = TRUE; } else { //
// When destroying a normal object, lock the Context that the
// object resides in.
//
ContextLock cl; if (cl.LockNL(ContextLock::edDefer, pctxThread)) { ObjectLock ol(pobj); CHECK_MODIFY();
pobj->xwDeleteHandle(); retval = TRUE; } } }
//
// NOTE: The object may not be deleted yet if there are any outstanding
// locks against it. If it is a Gadget, it may be locked by one of the
// message queues.
//
END_RECV_NOLOCK(); }
/***************************************************************************\
* * DUserDeleteGadget (API) * * TODO: Document this API * \***************************************************************************/
DUSER_API HRESULT WINAPI DUserDeleteGadget( IN DUser::Gadget * pg) { BEGIN_RECV_NOLOCK(HRESULT, E_INVALIDARG);
MsgObject * pmo = MsgObject::CastMsgObject(pg); if (pmo == NULL) { PromptInvalid("Must specify a valid Gadget to delete"); return E_INVALIDARG; }
{ //
// When destroying a normal object, lock the Context that the
// object resides in.
//
ContextLock cl; if (cl.LockNL(ContextLock::edDefer, pctxThread)) { ObjectLock ol(pmo); CHECK_MODIFY();
pmo->xwDeleteHandle(); retval = S_OK; } }
//
// NOTE: The object may not be deleted yet if there are any outstanding
// locks against it. If it is a Gadget, it may be locked by one of the
// message queues.
//
END_RECV_NOLOCK(); }
/***************************************************************************\
* * IsStartDelete (API) * * TODO: Document this API * \***************************************************************************/
DUSER_API BOOL WINAPI IsStartDelete( IN HANDLE hobj, IN BOOL * pfStarted) { BaseObject * pobj;
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_WRITE_PTR(pfStarted); VALIDATE_OBJECT(obj);
*pfStarted = pobj->IsStartDelete(); retval = TRUE;
END_RECV(); }
/***************************************************************************\
* * GetContext (API) * * TODO: Document this API * \***************************************************************************/
DUSER_API HDCONTEXT WINAPI GetContext( IN HANDLE h) { BEGIN_RECV_NOCONTEXT(HDCONTEXT, NULL);
// TODO: Totally rewrite this nonsense.
{ DuEventGadget * pgad; HGADGET hgad = (HGADGET) h; VALIDATE_EVENTGADGET_NOCONTEXT(gad); if (pgad != NULL) { retval = (HDCONTEXT) GetHandle(pgad->GetContext()); } }
END_RECV_NOCONTEXT(); }
/***************************************************************************\
* * IsInsideContext (API) * * TODO: Document this API * \***************************************************************************/
DUSER_API BOOL WINAPI IsInsideContext(HANDLE h) { BOOL fInside = FALSE;
if ((h != NULL) && IsInitThread()) { __try { DuEventGadget * pgad = ValidateBaseGadget((HGADGET) h); if (pgad != NULL) { Context * pctxThread = GetContext(); fInside = (pctxThread == pgad->GetContext()); } else if (BaseObject::ValidateHandle(h) != NULL) { fInside = TRUE; } } __except(EXCEPTION_EXECUTE_HANDLER) { fInside = FALSE; } }
return fInside; }
/***************************************************************************\
* * CreateGadget (API) * * CreateGadget() creates a new Gadget of a given type. Depending on the * specific flags, different Gadgets will actually be instantiated. Once a * Gadget of a specific type has been created, it can not be changed into a * different type without being deleted and recreated. * * <param name="nFlags"> * Specifies both what type of Gadget to created and any creation-time * properties of that Gadget * <table item="Value" desc="Action"> * GC_HWNDHOST Creates a top-level Gadget that can host a * GadgetTree inside the client area of a given * HWND. hParent must be a valid HWND. * GC_NCHOST Creates a top-level Gadget that can host a * GadgetTree inside the non-client area of a given * HWND. hParent must be a valid HWND. * GC_DXHOST Creates a top-level Gadget that can host a * GadgetTree inside a DXSurface. hParent must be * an LPCRECT specifying the area of the surface * the tree will be displayed on. * GC_COMPLEX Creates a sub-level Gadget that is optimized for * a complex subtree below it containing many other * Gadgets. More expensive than a Simple Gadget, * Complex Gadgets provide optimized region management * and are more equivalent to HWND's in both * functionality and design. hParent must specify a * valid HGADGET. * GC_SIMPLE Creates a sub-level Gadget that is optimized for * a simple subtree below it containing a few Gadgets. * Simple Gadgets are cheaper to create and often use * than Complex Gadgets if optimized region management * is not needed. hParent must specify a valid * HGADGET. * GC_DETACHED Creates a Gadget not integrated into a given Gadget * tree. Since they are separated from a tree, * operations must be explicitely forwarded to * Detached Gadgets during processing. hParent is * ignored. * GC_MESSAGE Creates a message-only Gadget that can receive and * send messages, but does not participate in any * visual or interactive manner. hParent is ignored. * </table> * </param> * * <return type="HGADGET"> Returns a handle to the newly created Gadget * or NULL if the creation failed.</> * <see type="function"> DeleteHandle</> * \***************************************************************************/
DUSER_API HGADGET WINAPI CreateGadget( IN HANDLE hParent, // Handle to parent
IN UINT nFlags, // Creation flags
IN GADGETPROC pfnProc, // Pointer to the Gadget procedure
IN void * pvGadgetData) // User data associated with this Gadget
{ BEGIN_RECV(HGADGET, NULL, ContextLock::edDefer);
HRESULT hr; CREATE_INFO ci; ci.pfnProc = pfnProc; ci.pvData = pvGadgetData;
switch (nFlags & GC_TYPE) { case GC_HWNDHOST: { HWND hwndContainer = (HWND) hParent; VALIDATE_HWND(wndContainer);
DuRootGadget * pgadRoot; hr = GdCreateHwndRootGadget(hwndContainer, &ci, &pgadRoot); SET_RETURN(hr, (HGADGET) GetHandle(pgadRoot)); } break;
case GC_NCHOST: { HWND hwndContainer = (HWND) hParent; VALIDATE_HWND(wndContainer);
DuRootGadget * pgadRoot; hr = GdCreateNcRootGadget(hwndContainer, &ci, &pgadRoot); SET_RETURN(hr, (HGADGET) GetHandle(pgadRoot)); } break;
case GC_DXHOST: { const RECT * prcContainerRect = (const RECT *) hParent; VALIDATE_READ_PTR_(prcContainerRect, sizeof(RECT));
DuRootGadget * pgadRoot; hr = GdCreateDxRootGadget(prcContainerRect, &ci, &pgadRoot); SET_RETURN(hr, (HGADGET) GetHandle(pgadRoot)); } break;
case GC_COMPLEX: PromptInvalid("Complex Gadgets are not yet implemented"); SetError(E_NOTIMPL); break;
case GC_SIMPLE: { DuVisual * pgadParent; HGADGET hgadParent = (HGADGET) hParent; VALIDATE_VISUAL_OR_NULL(gadParent);
if (pgadParent == NULL) { pgadParent = GetCoreSC()->pconPark->GetRoot(); if (pgadParent == NULL) { //
// The Parking Gadget has already been destroyed, so can not
// create a new child.
//
SetError(E_INVALIDARG); goto ErrorExit; } }
DuVisual * pgadChild; hr = pgadParent->AddChild(&ci, &pgadChild); SET_RETURN(hr, (HGADGET) GetHandle(pgadChild)); } break;
case GC_DETACHED: PromptInvalid("Detached Gadgets are not yet implemented"); SetError(E_NOTIMPL); break;
case GC_MESSAGE: { VALIDATE_VALUE(hParent, NULL); VALIDATE_CODE_PTR(pfnProc); // MsgGadget's must have a GadgetProc
DuListener * pgadNew; hr = DuListener::Build(&ci, &pgadNew); SET_RETURN(hr, (HGADGET) GetHandle(pgadNew)); } break;
default: PromptInvalid("Invalid Gadget type"); SetError(E_INVALIDARG); }
END_RECV(); }
/***************************************************************************\
* * GetGadgetFocus (API) * * GetGadgetFocus() returns the Gadget with current keyboard focus or NULL * if no Gadget currently has focus. * * <return type="HGADGET"> Gadget with keyboard focus.</> * <see type="function"> SetGadgetFocus</> * <see type="message"> GM_CHANGESTATE</> * \***************************************************************************/
DUSER_API HGADGET WINAPI GetGadgetFocus() { BEGIN_RECV(HGADGET, NULL, ContextLock::edNone);
retval = (HGADGET) GetHandle(DuRootGadget::GetFocus());
END_RECV(); }
/***************************************************************************\
* * SetGadgetFocus (API) * * SetGadgetFocus() moves keyboard focus to the specified Gadget. Both the * current Gadget with keyboard focus and the Gadget being specified will be * sent a GM_CHANGESTATE message with nCode=GSTATE_KEYBOARDFOCUS notifying of * the focus change. * * <return type="BOOL"> Focus was successfully moved.</> * <see type="function"> GetGadgetFocus</> * <see type="message"> GM_CHANGESTATE</> * \***************************************************************************/
DUSER_API BOOL WINAPI SetGadgetFocus( IN HGADGET hgadFocus) // Gadget to receive focus.
{ DuVisual * pgadFocus; DuRootGadget * pgadRoot;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_VISUAL(gadFocus); CHECK_MODIFY();
//
// TODO: Do we need to only allow the app to change focus if on the same
// thread? USER does this.
//
pgadRoot = pgadFocus->GetRoot(); if (pgadRoot != NULL) { retval = pgadRoot->xdSetKeyboardFocus(pgadFocus); }
END_RECV(); }
/***************************************************************************\
* * IsGadgetParentChainStyle (API) * * IsGadgetParentChainStyle() checks if a Gadget parent change has the * specified style bits set. * * <return type="BOOL"> Gadget was successfully checked.</> * <see type="function"> GetGadgetStyle</> * <see type="function"> SetGadgetStyle</> * \***************************************************************************/
DUSER_API BOOL WINAPI IsGadgetParentChainStyle( IN HGADGET hgad, // Gadget to check visibility
IN UINT nStyle, // Style bits to check
OUT BOOL * pfChain, // Chain state
IN UINT nFlags) // Optional flags
{ DuVisual * pgad;
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_VISUAL(gad); VALIDATE_VALUE(nFlags, 0); VALIDATE_FLAGS(nStyle, GS_VALID); VALIDATE_WRITE_PTR_(pfChain, sizeof(BOOL)); CHECK_MODIFY();
*pfChain = pgad->IsParentChainStyle(nStyle); retval = TRUE;
END_RECV(); }
/***************************************************************************\
* * SetGadgetFillI (API) * * SetGadgetFillI() specifies an optional brush to fill the Gadget's * background with when drawing. The background will be filled before the * Gadget is given the GM_PAINT message to draw. * * <return type="BOOL"> Fill was successfully set.</> * <see type="function"> UtilDrawBlendRect</> * <see type="message"> GM_PAINT</> * \***************************************************************************/
DUSER_API BOOL WINAPI SetGadgetFillI( IN HGADGET hgadChange, // Gadget to change
IN HBRUSH hbrFill, // Brush to fill with or NULL to remove
IN BYTE bAlpha, // Alpha level to apply brush
IN int w, // Optional width of brush when
// alpha-blending or 0 for default
IN int h) // Optional height of brush when
// alpha-blending or 0 for default
{ DuVisual * pgadChange; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_VISUAL(gadChange); CHECK_MODIFY();
hr = pgadChange->SetFill(hbrFill, bAlpha, w, h); SET_RETURN(hr, TRUE);
END_RECV(); }
/***************************************************************************\
* * SetGadgetFillF (API) * * SetGadgetFillF() specifies an optional brush to fill the Gadget's * background with when drawing. The background will be filled before the * Gadget is given the GM_PAINT message to draw. * * <return type="BOOL"> Fill was successfully set.</> * <see type="function"> UtilDrawBlendRect</> * <see type="message"> GM_PAINT</> * \***************************************************************************/
DUSER_API BOOL WINAPI SetGadgetFillF( IN HGADGET hgadChange, // Gadget to change
IN Gdiplus::Brush * pgpbr) // Brush to fill with or NULL to remove
{ DuVisual * pgadChange; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_VISUAL(gadChange); CHECK_MODIFY();
hr = pgadChange->SetFill(pgpbr); SET_RETURN(hr, TRUE);
END_RECV(); }
/***************************************************************************\
* * GetGadgetScale (API) * * GetGadgetScale() returns the Gadget's scaling factor. If the Gadget is * not scaled, the factors will be X=1.0, Y=1.0. * * <return type="BOOL"> Successfully returned scaling factor</> * <see type="function"> SetGadgetScale</> * <see type="function"> GetGadgetRotation</> * <see type="function"> SetGadgetRotation</> * <see type="function"> GetGadgetRect</> * <see type="function"> SetGadgetRect</> * \***************************************************************************/
DUSER_API BOOL WINAPI GetGadgetScale( IN HGADGET hgad, // Gadget to check
OUT float * pflX, // Horizontal scaling factor
OUT float * pflY) // Vertical scaling factor
{ DuVisual * pgad;
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_VISUAL(gad); VALIDATE_WRITE_PTR_(pflX, sizeof(float)); VALIDATE_WRITE_PTR_(pflY, sizeof(float));
pgad->GetScale(pflX, pflY); retval = TRUE;
END_RECV(); }
/***************************************************************************\
* * SetGadgetScale (API) * * SetGadgetScale() changes the specified Gadget's scaling factor. Scaling * is determined from the upper-left corner of the Gadget and is applied * dynamically during painting and hit-testing. The Gadget's logical * rectangle set by SetGadgetRect() does not change. * * When scaling is applied to a Gadget, the entire subtree of that Gadget is * scaled. To remove any scaling factor, use X=1.0, Y=1.0. * * <return type="BOOL"> Successfully changed scaling factor</> * <see type="function"> GetGadgetScale</> * <see type="function"> GetGadgetRotation</> * <see type="function"> SetGadgetRotation</> * <see type="function"> GetGadgetRect</> * <see type="function"> SetGadgetRect</> * \***************************************************************************/
DUSER_API BOOL WINAPI SetGadgetScale( IN HGADGET hgadChange, // Gadget to change
IN float flX, // New horizontal scaling factor
IN float flY) // New vertical scaling factor
{ DuVisual * pgadChange; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_VISUAL(gadChange); CHECK_MODIFY();
hr = pgadChange->xdSetScale(flX, flY); SET_RETURN(hr, TRUE);
END_RECV(); }
/***************************************************************************\
* * GetGadgetRotation (API) * * GetGadgetRotation() returns the Gadget's rotation factor in radians. If * a Gadget is not rotated, the factor will be 0.0. * * <return type="BOOL"> Successfully returned rotation factor</> * <see type="function"> GetGadgetScale</> * <see type="function"> SetGadgetScale</> * <see type="function"> SetGadgetRotation</> * <see type="function"> GetGadgetRect</> * <see type="function"> SetGadgetRect</> * \***************************************************************************/
DUSER_API BOOL WINAPI GetGadgetRotation( IN HGADGET hgad, // Gadget to check
OUT float * pflRotationRad) // Rotation factor in radians
{ DuVisual * pgad;
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_VISUAL(gad); VALIDATE_WRITE_PTR_(pflRotationRad, sizeof(float));
*pflRotationRad = pgad->GetRotation(); retval = TRUE;
END_RECV(); }
/***************************************************************************\
* * SetGadgetRotation (API) * * SetGadgetRotation() changes the specified Gadget's rotation factor in * radians. Scaling is determined from the upper-left corner of the Gadget * and is applied dynamically during painting and hit-testing. The Gadget's * logical rectangle set by SetGadgetRect() does not change. * * When rotation is applied to a Gadget, the entire subtree of that Gadget is * rotated. To remove any rotation factor, use 0.0. * * <return type="BOOL"> Successfully changed scaling factor</> * <see type="function"> GetGadgetScale</> * <see type="function"> SetGadgetScale</> * <see type="function"> GetGadgetRotation</> * <see type="function"> GetGadgetRect</> * <see type="function"> SetGadgetRect</> * \***************************************************************************/
DUSER_API BOOL WINAPI SetGadgetRotation( IN HGADGET hgadChange, // Gadget to change
IN float flRotationRad) // New rotation factor in radians
{ DuVisual * pgadChange; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_VISUAL(gadChange); CHECK_MODIFY();
hr = pgadChange->xdSetRotation(flRotationRad); SET_RETURN(hr, TRUE);
END_RECV(); }
//------------------------------------------------------------------------------
DUSER_API BOOL WINAPI GetGadgetCenterPoint(HGADGET hgad, float * pflX, float * pflY) { DuVisual * pgad;
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_VISUAL(gad); VALIDATE_WRITE_PTR_(pflX, sizeof(float)); VALIDATE_WRITE_PTR_(pflY, sizeof(float));
pgad->GetCenterPoint(pflX, pflY); retval = TRUE;
END_RECV(); }
//------------------------------------------------------------------------------
DUSER_API BOOL WINAPI SetGadgetCenterPoint(HGADGET hgadChange, float flX, float flY) { DuVisual * pgadChange; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_VISUAL(gadChange); CHECK_MODIFY();
hr = pgadChange->xdSetCenterPoint(flX, flY); SET_RETURN(hr, TRUE);
END_RECV(); }
//------------------------------------------------------------------------------
DUSER_API BOOL WINAPI GetGadgetBufferInfo( IN HGADGET hgad, // Gadget to check
OUT BUFFER_INFO * pbi) // Buffer information
{ DuVisual * pgad; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_VISUAL(gad); VALIDATE_WRITE_STRUCT(pbi, BUFFER_INFO); VALIDATE_FLAGS(pbi->nMask, GBIM_VALID);
if (!pgad->IsBuffered()) { PromptInvalid("Gadget is not GS_BUFFERED"); SetError(DU_E_NOTBUFFERED); goto ErrorExit; }
hr = pgad->GetBufferInfo(pbi); SET_RETURN(hr, TRUE);
END_RECV(); }
//------------------------------------------------------------------------------
DUSER_API BOOL WINAPI SetGadgetBufferInfo( IN HGADGET hgadChange, // Gadget to change
IN const BUFFER_INFO * pbi) // Buffer information
{ DuVisual * pgadChange; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_VISUAL(gadChange); VALIDATE_READ_STRUCT(pbi, BUFFER_INFO); VALIDATE_FLAGS(pbi->nMask, GBIM_VALID);
if (!pgadChange->IsBuffered()) { PromptInvalid("Gadget is not GS_BUFFERED"); SetError(DU_E_NOTBUFFERED); goto ErrorExit; }
hr = pgadChange->SetBufferInfo(pbi); SET_RETURN(hr, TRUE);
END_RECV(); }
//------------------------------------------------------------------------------
DUSER_API BOOL WINAPI GetGadgetRgn( IN HGADGET hgad, // Gadget to get region of
IN UINT nRgnType, // Type of region
OUT HRGN hrgn, // Specified region
IN UINT nFlags) // Modifying flags
{ DuVisual * pgad; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_VISUAL(gad); VALIDATE_RANGE(nRgnType, GRT_MIN, GRT_MAX); VALIDATE_REGION(rgn); hr = pgad->GetRgn(nRgnType, hrgn, nFlags); SET_RETURN(hr, TRUE);
END_RECV(); }
//------------------------------------------------------------------------------
DUSER_API BOOL WINAPI GetGadgetRootInfo( IN HGADGET hgadRoot, // RootGadget to modify
IN ROOT_INFO * pri) // Information
{ DuRootGadget * pgadRoot;
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_ROOTGADGET(gadRoot); VALIDATE_WRITE_STRUCT(pri, ROOT_INFO); VALIDATE_FLAGS(pri->nMask, GRIM_VALID);
pgadRoot->GetInfo(pri); retval = TRUE;
END_RECV(); }
//------------------------------------------------------------------------------
DUSER_API BOOL WINAPI SetGadgetRootInfo( IN HGADGET hgadRoot, // RootGadget to modify
IN const ROOT_INFO * pri) // Information
{ DuRootGadget * pgadRoot; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_ROOTGADGET(gadRoot); VALIDATE_READ_STRUCT(pri, ROOT_INFO); VALIDATE_FLAGS(pri->nMask, GRIM_VALID); VALIDATE_FLAGS(pri->nOptions, GRIO_VALID); VALIDATE_RANGE(pri->nSurface, GSURFACE_MIN, GSURFACE_MAX); VALIDATE_RANGE(pri->nDropTarget, GRIDT_MIN, GRIDT_MAX);
hr = pgadRoot->SetInfo(pri); SET_RETURN(hr, TRUE);
END_RECV(); }
//------------------------------------------------------------------------------
DUSER_API HRESULT WINAPI DUserSendMethod( IN MethodMsg * pmsg) // Message to send
{ Context * pctxGad, * pctxSend; HGADGET hgadMsg; MsgObject * pmo; UINT nResult; HRESULT hr; UINT hm;
//
// Validation for DUserSendMethod() is a little unusual because the
// caller doesn't need to be in the same Context as the Gadget itself. This
// means we need to get the Context from the Gadget and not use TLS.
//
// The Caller must be initialized, but we WON'T take the context-lock.
// TODO: Investigate whether we should actually do this because it may
// allow us to take off the lock on the DUserHeap.
//
// NOTE: This code has been HIGHLY optimized so that in-context Send
// messages will be as fast as possible.
//
nResult = DU_S_NOTHANDLED; if ((pmsg == NULL) || ((hgadMsg = pmsg->hgadMsg) == NULL) || (pmsg->nMsg >= GM_EVENT)) { PromptInvalid("Invalid parameters to SendGadgetMethod()"); hr = E_INVALIDARG; goto Exit; }
pmo = reinterpret_cast<MsgObject *>(hgadMsg); hm = pmo->GetHandleMask(); if (!TestFlag(hm, hmMsgObject)) { PromptInvalid("Object is not a valid Gadget"); hr = E_INVALIDARG; goto Exit; }
if (TestFlag(hm, hmEventGadget)) { DuEventGadget * pgadMsg = static_cast<DuEventGadget *>(pmo); pctxSend = RawGetContext(); pctxGad = pgadMsg->GetContext(); AssertMsg(pctxGad != NULL, "Fully created DuEventGadget must have a Context");
if (pctxSend->IsOrphanedNL() || pctxGad->IsOrphanedNL()) { PromptInvalid("Illegally using an orphaned Context"); hr = E_INVALIDARG; goto Exit; }
if (pctxSend == pctxGad) { pmo->InvokeMethod(pmsg); hr = S_OK; goto Exit; } else { hr = GetCoreSC(pctxSend)->xwSendMethodNL(GetCoreSC(pctxGad), pmsg, pmo); } } else { //
// For non-BaseGadgets, use the current context. This means that we can
// invoke directly.
//
pmo->InvokeMethod(pmsg); hr = S_OK; }
Exit: return hr; }
/***************************************************************************\
* * SendGadgetEvent (API) * * SendGadgetEvent() sends a message to the specified Gadget. The function * calls the Gadget procedure and does not return until the Gadget has * processed the message. * * <param name="pmsg"> * Several members of the GMSG must be previously filled to correctly send * the message to the specified Gadget. * <table item="Field" desc="Description"> * cbSize Size of the message being sent in bytes. * nMsg ID of the message. * hgadMsg Gadget that the message is being sent to. * result Default result value. * </table> * </param> * * <param nane="nFlags"> * Specifies optional flags to modify how the message is sent to the Gadget. * <table item="Value" desc="Action"> * SGM_BUBBLE The message will be fully routed and bubbled inside * the Gadget Tree. If this flag is not specified, the * message will only be sent directly to the Gadget and * any attached Message Handlers. * </table> * </param> * * <return type="UINT"> * Return value specifying how message was handled: * <table item="Value" desc="Action"> * GPR_COMPLETE The message was completely handled by a Gadget * in the processing loop. * GPR_PARTIAL The message was partially handled by one or * more Gadget in the processing loop, but was never * completely handled. * GPR_NOTHANDLED The message was never handled by any Gadgets in * the processing loop. * </table> * </return> * * <see type="function"> RegisterGadgetMessage</> * <see type="function"> RegisterGadgetMessageString</> * <see type="function"> UnregisterGadgetMessage</> * <see type="function"> UnregisterGadgetMessageString</> * <see type="function"> AddGadgetMessageHandler</> * <see type="function"> RemoveGadgetMessageHandler</> * <see type="struct"> GMSG</> * <see type="article"> GadgetMessaging</> * \***************************************************************************/
DUSER_API HRESULT WINAPI DUserSendEvent( IN EventMsg * pmsg, // Message to send
IN UINT nFlags) // Optional flags to modifying sending
{ Context * pctxGad, * pctxSend; HGADGET hgadMsg; DuEventGadget * pgad; HRESULT nResult; UINT hm;
//
// Validation for SendGadgetEvent() is a little unusual because the
// caller doesn't need to be in the same Context as the Gadget itself. This
// means we need to get the Context from the Gadget and not use TLS.
//
// The Caller must be initialized, but we WON'T take the context-lock.
// TODO: Investigate whether we should actually do this because it may
// allow us to take off the lock on the DUserHeap.
//
// NOTE: This code has been HIGHLY optimized so that in-context Send
// messages will be as fast as possible.
//
nResult = E_INVALIDARG; if ((pmsg == NULL) || ((hgadMsg = pmsg->hgadMsg) == NULL) || (pmsg->nMsg < GM_EVENT)) { PromptInvalid("Invalid parameters to SendGadgetEvent()"); goto Error; }
pgad = reinterpret_cast<DuEventGadget *>(hgadMsg); hm = pgad->GetHandleMask(); if (!TestFlag(hm, hmEventGadget)) { PromptInvalid("Object is not a valid BaseGadget"); goto Error; }
pctxSend = RawGetContext(); pctxGad = pgad->GetContext(); AssertMsg(pctxGad != NULL, "Fully created DuEventGadget must have a Context");
if (pctxSend->IsOrphanedNL() || pctxGad->IsOrphanedNL()) { PromptInvalid("Illegally using an orphaned Context"); goto Error; }
if (pctxSend == pctxGad) { const GPCB & cb = pgad->GetCallback(); if (TestFlag(nFlags, SGM_FULL) && TestFlag(hm, hmVisual)) { nResult = cb.xwInvokeFull((const DuVisual *) pgad, pmsg, 0); } else { nResult = cb.xwInvokeDirect(pgad, pmsg, 0); } } else { nResult = GetCoreSC(pctxSend)->xwSendEventNL(GetCoreSC(pctxGad), pmsg, pgad, nFlags); }
return nResult;
Error: return E_INVALIDARG; }
//------------------------------------------------------------------------------
DUSER_API HRESULT WINAPI DUserPostMethod( IN MethodMsg * pmsg) // Message to post
{ Context * pctxGad, * pctxSend; HGADGET hgadMsg; MsgObject * pmo; UINT nResult; HRESULT hr; UINT hm;
//
// Validation for PostGadgetEvent() is a little unusual because the
// caller doesn't need to be in the same Context as the Gadget itself. This
// means we need to get the Context from the Gadget and not use TLS.
//
nResult = DU_S_NOTHANDLED; if ((pmsg == NULL) || ((hgadMsg = pmsg->hgadMsg) == NULL) || (pmsg->nMsg >= GM_EVENT)) { PromptInvalid("Invalid parameters to DUserPostMethod()"); hr = E_INVALIDARG; goto Exit; }
pmo = reinterpret_cast<MsgObject *>(hgadMsg); hm = pmo->GetHandleMask(); if (!TestFlag(hm, hmMsgObject)) { PromptInvalid("Object is not a valid Gadget"); hr = E_INVALIDARG; goto Exit; }
if (TestFlag(hm, hmEventGadget)) { DuEventGadget * pgad = static_cast<DuEventGadget *>(pmo); pctxSend = RawGetContext(); pctxGad = pgad->GetContext(); AssertMsg(pctxGad != NULL, "Fully created Gadgets must have a Context"); } else { //
// For non-BaseGadgets, use the current context.
//
pctxSend = pctxGad = GetContext(); if (pctxGad == NULL) { PromptInvalid("Must initialize Context before using thread"); hr = DU_E_NOCONTEXT; goto Exit; } }
if (pctxSend->IsOrphanedNL() || pctxGad->IsOrphanedNL()) { PromptInvalid("Illegally using an orphaned Context"); hr = E_INVALIDARG; goto Exit; }
hr = GetCoreSC(pctxSend)->PostMethodNL(GetCoreSC(pctxGad), pmsg, pmo);
Exit: return hr; }
/***************************************************************************\
* * DUserPostEvent (API) * * DUserPostEvent() posts a message to the specified Gadget. The function * calls the Gadget procedure and returns after the message has bee successfully * posted to the owning messsage queue. * * <param name="pmsg"> * Several members of the GMSG must be previously filled to correctly send * the message to the specified Gadget. * <table item="Field" desc="Description"> * cbSize Size of the message being sent in bytes. * nMsg ID of the message. * hgadMsg Gadget that the message is being sent to. * result Default result value. * </table> * </param> * * <param nane="nFlags"> * Specifies optional flags to modify how the message is sent to the Gadget. * <table item="Value" desc="Action"> * SGM_BUBBLE The message will be fully routed and bubbled inside * the Gadget Tree. If this flag is not specified, the * message will only be sent directly to the Gadget and * any attached Message Handlers. * </table> * </param> * * <return type="BOOL"> * Message was successfully posted to the destination Gadget's queue. * </return> * * <see type="function"> SendGadgetEvent</> * <see type="function"> RegisterGadgetMessage</> * <see type="function"> RegisterGadgetMessageString</> * <see type="function"> UnregisterGadgetMessage</> * <see type="function"> UnregisterGadgetMessageString</> * <see type="function"> AddGadgetMessageHandler</> * <see type="function"> RemoveGadgetMessageHandler</> * <see type="struct"> GMSG</> * <see type="article"> GadgetMessaging</> * \***************************************************************************/
DUSER_API HRESULT WINAPI DUserPostEvent( IN EventMsg * pmsg, // Message to post
IN UINT nFlags) // Optional flags modifiying posting
{ Context * pctxGad; HGADGET hgad; DuEventGadget * pgad; HRESULT hr;
//
// Validation for PostGadgetEvent() is a little unusual because the
// caller doesn't need to be in the same Context as the Gadget itself. This
// means we need to get the Context from the Gadget and not use TLS.
//
BEGIN_RECV_NOCONTEXT(BOOL, FALSE); VALIDATE_READ_PTR_(pmsg, pmsg->cbSize); VALIDATE_FLAGS(nFlags, SGM_VALID);
if (pmsg->nMsg < GM_EVENT) { PromptInvalid("Can not post private messages"); SetError(E_INVALIDARG); goto ErrorExit; }
if (!IsInitContext()) { PromptInvalid("Must initialize Context before using thread"); SetError(DU_E_NOCONTEXT); goto ErrorExit; }
hgad = pmsg->hgadMsg; VALIDATE_EVENTGADGET_NOCONTEXT(gad); pctxGad = pgad->GetContext();
if (pctxGad->IsOrphanedNL()) { PromptInvalid("Illegally using an orphaned Context"); goto ErrorExit; }
hr = GetCoreSC()->PostEventNL(GetCoreSC(pctxGad), pmsg, pgad, nFlags); SET_RETURN(hr, TRUE);
END_RECV_NOCONTEXT(); }
//------------------------------------------------------------------------------
DUSER_API BOOL WINAPI FireGadgetMessages( IN FGM_INFO * rgFGM, // Collection of messsages to fire
IN int cMsgs, // Number of messages
IN UINT idQueue) // Queue to send messages
{ Context * pctxGad, * pctxCheck; HGADGET hgad; DuEventGadget * pgad; HRESULT hr; int idx;
//
// Validation for FireGadgetMessages() is a little unusual because the
// caller doesn't need to be in the same Context as the Gadget itself. This
// means we need to get the Context from the Gadget and not use TLS.
//
BEGIN_RECV_NOCONTEXT(BOOL, FALSE); if (cMsgs <= 0) { PromptInvalid("Must specify a valid number of messages to process."); SetError(E_INVALIDARG); goto ErrorExit; }
hgad = rgFGM[0].pmsg->hgadMsg; VALIDATE_EVENTGADGET_NOCONTEXT(gad); pctxGad = pgad->GetContext();
for (idx = 0; idx < cMsgs; idx++) { FGM_INFO & fgm = rgFGM[idx];
EventMsg * pmsg = fgm.pmsg; VALIDATE_READ_PTR_(pmsg, pmsg->cbSize); VALIDATE_FLAGS(fgm.nFlags, SGM_VALID); if (pmsg->nMsg <= 0) { PromptInvalid("Can not post private messages"); SetError(E_INVALIDARG); goto ErrorExit; }
if (TestFlag(fgm.nFlags, SGM_RECEIVECONTEXT)) { PromptInvalid("Can not use SGM_RECEIVECONTEXT with FireGadgetMessage"); SetError(E_INVALIDARG); goto ErrorExit; }
hgad = pmsg->hgadMsg; VALIDATE_EVENTGADGET_NOCONTEXT(gad); pctxCheck = pgad->GetContext(); if (pctxCheck != pctxGad) { PromptInvalid("All Gadgets must be inside the same Context"); SetError(DU_E_INVALIDCONTEXT); goto ErrorExit; }
//
// Store the validated Gadget back so that it doesn't need to be
// revalidated.
//
fgm.pvReserved = pgad; }
hr = GetCoreSC()->xwFireMessagesNL(GetCoreSC(pctxGad), rgFGM, cMsgs, idQueue); SET_RETURN(hr, TRUE);
END_RECV_NOCONTEXT(); }
/***************************************************************************\
* * GetMessageEx (API) * \***************************************************************************/
DUSER_API BOOL WINAPI GetMessageExA( IN LPMSG lpMsg, IN HWND hWnd, IN UINT wMsgFilterMin, IN UINT wMsgFilterMax) { BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
Context * pctxThread = RawGetContext(); if (pctxThread == NULL) { retval = GetMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); } else { retval = GetCoreSC(pctxThread)->xwProcessNL(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, PM_REMOVE, CoreSC::smGetMsg | CoreSC::smAnsi); }
END_RECV_NOCONTEXT(); }
DUSER_API BOOL WINAPI GetMessageExW( IN LPMSG lpMsg, IN HWND hWnd, IN UINT wMsgFilterMin, IN UINT wMsgFilterMax) { BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
Context * pctxThread = RawGetContext(); if (pctxThread == NULL) { retval = GetMessageW(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); } else { retval = GetCoreSC(pctxThread)->xwProcessNL(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, PM_REMOVE, CoreSC::smGetMsg); }
END_RECV_NOCONTEXT(); }
/***************************************************************************\
* * PeekMessageEx (API) * \***************************************************************************/
DUSER_API BOOL WINAPI PeekMessageExA( IN LPMSG lpMsg, IN HWND hWnd, IN UINT wMsgFilterMin, IN UINT wMsgFilterMax, IN UINT wRemoveMsg) { BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
Context * pctxThread = RawGetContext(); if (pctxThread == NULL) { retval = PeekMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); } else { retval = GetCoreSC(pctxThread)->xwProcessNL(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, CoreSC::smAnsi); }
END_RECV_NOCONTEXT(); }
DUSER_API BOOL WINAPI PeekMessageExW( IN LPMSG lpMsg, IN HWND hWnd, IN UINT wMsgFilterMin, IN UINT wMsgFilterMax, IN UINT wRemoveMsg) { BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
Context * pctxThread = RawGetContext(); if (pctxThread == NULL) { retval = PeekMessageW(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); } else { retval = GetCoreSC(pctxThread)->xwProcessNL(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, 0); }
END_RECV_NOCONTEXT(); }
/***************************************************************************\
* * WaitMessageEx (API) * \***************************************************************************/
DUSER_API BOOL WINAPI WaitMessageEx() { BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
Context * pctxThread = RawGetContext(); if (pctxThread == NULL) { retval = WaitMessage(); } else { AssertInstance(pctxThread); GetCoreSC(pctxThread)->WaitMessage(); retval = TRUE; }
END_RECV_NOCONTEXT(); }
/***************************************************************************\
* * RegisterGadgetMessage (API) * * RegisterGadgetMessage() defines a new private Gadget message that is * guaranteed to be unique throughout the process. This MSGID can be used * when calling SendGadgetEvent or PostGadgetEvent. The MSGID is only * valid for the lifetime of the process. * * <remarks> * Multiple calls to RegisterGadgetMessage() with the same ID will produce * the same MSGID. * * RegisterGadgetMessage() differs in use from RegisterWindowMessage() in * that Gadgets are encouraged to use RegisterGadgetMessage() for all * private messages. This helps with version compatibility problems where * newer Gadget control implementations may use additional message and could * potentially overrun any static MSGID assignments. * * The MSGID's returned from RegisterGadgetMessage() and * RegisterGadgetMessageString() are guaranteed to not conflict with each * other. However, RegisterGadgetMessage() is the preferred mechanism for * registering private messages because of the reduced likelihood of * ID conflicts. * </remarks> * * <return type="MSGID"> ID of new message or 0 if failed.</> * <see type="function"> SendGadgetEvent</> * <see type="function"> RegisterGadgetMessageString</> * <see type="function"> UnregisterGadgetMessage</> * <see type="function"> UnregisterGadgetMessageString</> * <see type="function"> AddGadgetMessageHandler</> * <see type="function"> RemoveGadgetMessageHandler</> * <see type="struct"> GMSG</> * <see type="article"> GadgetMessaging</> * \***************************************************************************/
DUSER_API MSGID WINAPI RegisterGadgetMessage( IN const GUID * pguid) // Unique GUID of message to register
{ HRESULT hr; MSGID msgid;
BEGIN_RECV_NOCONTEXT(MSGID, PRID_Unused);
hr = DuEventPool::RegisterMessage(pguid, ptGlobal, &msgid); SET_RETURN(hr, msgid);
END_RECV_NOCONTEXT(); }
/***************************************************************************\
* * RegisterGadgetMessageString (API) * * RegisterGadgetMessageString() defines a new private Gadget message that is * guaranteed to be unique throughout the process. This MSGID can be used * when calling SendGadgetEvent() or PostGadgetEvent(). The MSGID is only * valid for the lifetime of the process. * * <remarks> * See RegisterGadgetMessage() for more information about MSGID's. * </remarks> * * <return type="MSGID"> ID of new message or 0 if failed.</> * <see type="function"> SendGadgetEvent</> * <see type="function"> RegisterGadgetMessage</> * <see type="function"> UnregisterGadgetMessage</> * <see type="function"> UnregisterGadgetMessageString</> * <see type="function"> AddGadgetMessageHandler</> * <see type="function"> RemoveGadgetMessageHandler</> * <see type="struct"> GMSG</> * <see type="article"> GadgetMessaging</> * \***************************************************************************/
DUSER_API MSGID WINAPI RegisterGadgetMessageString( IN LPCWSTR pszName) // Unique string ID of message to register
{ HRESULT hr; MSGID msgid;
BEGIN_RECV_NOCONTEXT(MSGID, PRID_Unused); VALIDATE_STRINGW_PTR(pszName, 128);
hr = DuEventPool::RegisterMessage(pszName, ptGlobal, &msgid); SET_RETURN(hr, msgid);
END_RECV_NOCONTEXT(); }
/***************************************************************************\
* * UnregisterGadgetMessage (API) * * UnregisterGadgetMessage() decreases the reference count of a private * message by one. When the reference count reaches 0, resources allocated * to store information about that private message are released, and the * MSGID is no longer valid. * * <return type="BOOL"> Message was successfully unregistered.</> * <see type="function"> SendGadgetEvent</> * <see type="function"> RegisterGadgetMessage</> * <see type="function"> RegisterGadgetMessageString</> * <see type="function"> UnregisterGadgetMessageString</> * <see type="function"> AddGadgetMessageHandler</> * <see type="function"> RemoveGadgetMessageHandler</> * <see type="struct"> GMSG</> * <see type="article"> GadgetMessaging</> * \***************************************************************************/
DUSER_API BOOL WINAPI UnregisterGadgetMessage( IN const GUID * pguid) // Unique GUID of message to unregister
{ HRESULT hr;
BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
hr = DuEventPool::UnregisterMessage(pguid, ptGlobal); SET_RETURN(hr, TRUE);
END_RECV_NOCONTEXT(); }
/***************************************************************************\
* * UnregisterGadgetMessageString (API) * * UnregisterGadgetMessageString() decreases the reference count of a private * message by one. When the reference count reaches 0, resources allocated * to store information about that private message are released, and the * MSGID is no longer valid. * * <return type="BOOL"> Message was successfully unregistered.</> * <see type="function"> SendGadgetEvent</> * <see type="function"> RegisterGadgetMessage</> * <see type="function"> RegisterGadgetMessageString</> * <see type="function"> UnregisterGadgetMessage</> * <see type="function"> AddGadgetMessageHandler</> * <see type="function"> RemoveGadgetMessageHandler</> * <see type="struct"> GMSG</> * <see type="article"> GadgetMessaging</> * \***************************************************************************/
DUSER_API BOOL WINAPI UnregisterGadgetMessageString( IN LPCWSTR pszName) // Unique string ID of message to register
{ HRESULT hr;
BEGIN_RECV_NOCONTEXT(BOOL, FALSE); VALIDATE_STRINGW_PTR(pszName, 128);
hr = DuEventPool::UnregisterMessage(pszName, ptGlobal); SET_RETURN(hr, TRUE);
END_RECV_NOCONTEXT(); }
//------------------------------------------------------------------------------
DUSER_API BOOL WINAPI FindGadgetMessages( IN const GUID ** rgpguid, // GUID's of messages to find
OUT MSGID * rgnMsg, // MSGID's of corresponding to messages
IN int cMsgs) // Number of messages
{ HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_RANGE(cMsgs, 1, 1000); // Ensure don't have an excessive number of lookups
hr = DuEventPool::FindMessages(rgpguid, rgnMsg, cMsgs, ptGlobal); SET_RETURN(hr, TRUE);
END_RECV(); }
/***************************************************************************\
* * AddGadgetMessageHandler (API) * * AddGadgetMessageHandler() adds a given Gadget to the list of message * handlers for another Gadget. Messages that are sent directly to hgadMsg * will also be sent to hgadHandler as an GMF_EVENT. * * <remarks> * A message handler can be any Gadget. Once registered, hgadHandler will * receive all messages sent to hgadMsg with a corresponding MSGID. Any * valid public or private message can be listened it. If nMsg==0, all * messages will be sent to hgadHandler. * * A single hgadHandler may be registered multiple times to handle different * messages from hgadMsg. * </remarks> * * <return type="BOOL"> Handler was successfully added.</> * <see type="function"> SendGadgetEvent</> * <see type="function"> RegisterGadgetMessage</> * <see type="function"> RegisterGadgetMessageString</> * <see type="function"> UnregisterGadgetMessage</> * <see type="function"> UnregisterGadgetMessageString</> * <see type="function"> RemoveGadgetMessageHandler</> * <see type="struct"> GMSG</> * <see type="article"> GadgetMessaging</> * \***************************************************************************/
DUSER_API BOOL WINAPI AddGadgetMessageHandler( IN HGADGET hgadMsg, // Gadget to attach to
IN MSGID nMsg, // Message to watch for
IN HGADGET hgadHandler) // Gadget to notify
{ DuEventGadget * pgadMsg; DuEventGadget * pgadHandler; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_EVENTGADGET(gadMsg); VALIDATE_EVENTGADGET(gadHandler); if (((nMsg < PRID_GlobalMin) && (nMsg > 0)) || (nMsg < 0)) { PromptInvalid("nMsg must be a valid MSGID"); goto ErrorExit; } CHECK_MODIFY();
hr = pgadMsg->AddMessageHandler(nMsg, pgadHandler); SET_RETURN(hr, TRUE);
END_RECV(); }
/***************************************************************************\
* * RemoveGadgetMessageHandler (API) * * RemoveGadgetMessageHandler() removes the specified hgadHandler from the * list of message handlers attached to hgadMsg. Only the first hgadHandler * with a corresponding nMsg will be removed. * * <return type="BOOL"> Handler was successfully removed.</> * <see type="function"> SendGadgetEvent</> * <see type="function"> RegisterGadgetMessage</> * <see type="function"> RegisterGadgetMessageString</> * <see type="function"> UnregisterGadgetMessage</> * <see type="function"> UnregisterGadgetMessageString</> * <see type="function"> AddGadgetMessageHandler</> * <see type="struct"> GMSG</> * <see type="article"> GadgetMessaging</> * \***************************************************************************/
DUSER_API BOOL WINAPI RemoveGadgetMessageHandler( IN HGADGET hgadMsg, // Gadget to detach from
IN MSGID nMsg, // Message being watched for
IN HGADGET hgadHandler) // Gadget being notified
{ DuEventGadget * pgadMsg; DuEventGadget * pgadHandler; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_EVENTGADGET(gadMsg); VALIDATE_EVENTGADGET(gadHandler); if (((nMsg < PRID_GlobalMin) && (nMsg > 0)) || (nMsg < 0)) { PromptInvalid("nMsg must be a valid MSGID"); goto ErrorExit; } CHECK_MODIFY();
hr = pgadMsg->RemoveMessageHandler(nMsg, pgadHandler); SET_RETURN(hr, TRUE);
END_RECV(); }
/***************************************************************************\
* * GetGadgetStyle (API) * * GetGadgetStyle() returns the current style of the given Gadget. * * <remarks> * For a list of Gadget styles, see SetGadgetStyle(). * </remarks> * * <return type="UINT"> Current style of Gadget.</> * <see type="function"> SetGadgetStyle</> * <see type="article"> GadgetStyles</> * \***************************************************************************/
DUSER_API UINT WINAPI GetGadgetStyle( IN HGADGET hgad) // Handle of Gadget
{ DuVisual * pgad;
BEGIN_RECV(UINT, 0, ContextLock::edNone); VALIDATE_VISUAL(gad);
retval = pgad->GetStyle();
END_RECV(); }
/***************************************************************************\
* * SetGadgetStyle (API) * * SetGadgetStyle() changes the current style of the given Gadget. Only the * styles specified by nMask are actually changed. If multiple style changes * are requested, but any changes fail, the successfully change styles will * not be reverted back. * * <param name="nNewStyle"> * nNewStyle can be a combination of the following flags: * <table item="Value" desc="Meaning"> * GS_RELATIVE The position of the Gadget is internally stored * relative to parent. This is the preferred style * if the Gadget will be moved more frequently, * such as when scrolling. * GS_VISIBLE The Gadget is visible. * GS_ENABLED The Gadget can receive input. * GS_BUFFERED Drawing of the Gadget is double-buffered. * GS_ALLOWSUBCLASS Gadget supports being subclassed. * GS_WANTFOCUS Gadget can receive keyboard focus. * GS_CLIPINSIDE Drawing of this Gadget will be clipped inside * the Gadget. * GS_CLIPSIBLINGS Drawing of this Gadget will exclude any area of * overlapping siblings that are higher in z-order. * GS_OPAQUE HINT: Support for composited drawing is * unnecessary. * GS_ZEROORIGIN Set the origin to (0,0) * </table> * </param> * * <return type="BOOL"> All style changes were successful.</> * <see type="function"> GetGadgetStyle</> * <see type="article"> GadgetStyles</> * \***************************************************************************/
DUSER_API BOOL WINAPI SetGadgetStyle( IN HGADGET hgadChange, // Gadget to change
IN UINT nNewStyle, // New style
IN UINT nMask) // Style bits to change
{ DuVisual * pgadChange; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_VISUAL(gadChange); VALIDATE_FLAGS(nNewStyle, GS_VALID); VALIDATE_FLAGS(nMask, GS_VALID); CHECK_MODIFY();
hr = pgadChange->xdSetStyle(nNewStyle, nMask); SET_RETURN(hr, TRUE);
END_RECV(); }
//------------------------------------------------------------------------------
DUSER_API PRID WINAPI RegisterGadgetProperty( IN const GUID * pguid) // Unique GUID of message to register
{ HRESULT hr; PRID prid;
BEGIN_RECV_NOCONTEXT(PRID, PRID_Unused);
hr = DuVisual::RegisterPropertyNL(pguid, ptGlobal, &prid); SET_RETURN(hr, prid);
END_RECV_NOCONTEXT(); }
//------------------------------------------------------------------------------
DUSER_API BOOL WINAPI UnregisterGadgetProperty( const GUID * pguid) { HRESULT hr;
BEGIN_RECV_NOCONTEXT(BOOL, FALSE);
hr = DuVisual::UnregisterPropertyNL(pguid, ptGlobal); SET_RETURN(hr, TRUE);
END_RECV_NOCONTEXT(); }
//------------------------------------------------------------------------------
DUSER_API BOOL WINAPI GetGadgetProperty(HGADGET hgad, PRID id, void ** ppvValue) { DuVisual * pgad; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_VISUAL(gad); VALIDATE_WRITE_PTR_(ppvValue, sizeof(ppvValue)); CHECK_MODIFY();
hr = pgad->GetProperty(id, ppvValue); SET_RETURN(hr, TRUE);
END_RECV(); }
//------------------------------------------------------------------------------
DUSER_API BOOL WINAPI SetGadgetProperty(HGADGET hgad, PRID id, void * pvValue) { DuVisual * pgad; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_VISUAL(gad); CHECK_MODIFY();
hr = pgad->SetProperty(id, pvValue); SET_RETURN(hr, TRUE);
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI RemoveGadgetProperty(HGADGET hgad, PRID id) { DuVisual * pgad;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_VISUAL(gad); CHECK_MODIFY();
pgad->RemoveProperty(id, FALSE /* Can't free memory for Global property*/); retval = TRUE;
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI EnumGadgets(HGADGET hgadEnum, GADGETENUMPROC pfnProc, void * pvData, UINT nFlags) { DuVisual * pgadEnum; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_FLAGS(nFlags, GENUM_VALID); VALIDATE_VISUAL(gadEnum); VALIDATE_CODE_PTR(pfnProc); CHECK_MODIFY();
hr = pgadEnum->xwEnumGadgets(pfnProc, pvData, nFlags); SET_RETURN(hr, TRUE);
END_RECV(); }
/***************************************************************************\
* * GetGadgetSize (API) * * GetGadgetSize() is a high-performance mechanism of retreiving the Gadget's * logical size. * * <return type="BOOL"> Successfully returned size in logical pixels.</> * <see type="function"> GetGadgetRect</> * <see type="function"> SetGadgetRect</> * <see type="article"> GadgetStyles</> * \***************************************************************************/
DUSER_API BOOL WINAPI GetGadgetSize( IN HGADGET hgad, // Handle of Gadget
OUT SIZE * psizeLogicalPxl) // Size in logical pixels
{ DuVisual * pgad;
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_VISUAL(gad); VALIDATE_WRITE_PTR_(psizeLogicalPxl, sizeof(SIZE));
pgad->GetSize(psizeLogicalPxl); retval = TRUE;
END_RECV(); }
/***************************************************************************\
* * GetGadgetRect (API) * * GetGadgetRect() is a flexible mechanism of retreiving the Gadget's * logical rectangle or actual bounding box. * * <param name=nFlags> * nFlags can be a combination of the following flags: * <table item="Value" desc="Meaning"> * SGR_CLIENT Coordinates are relative to the Gadget itself. * SGR_PARENT Coordinates are relative to the Gadget's parent. * SGR_CONTAINER Coordinates are relative to the Gadget's root * container. * SGR_DESKTOP Coordinates are relative to the Windows desktop. * SGR_ACTUAL Return the bounding rectangle of the Gadget. If * this flag is specified, a bounding box is * computed from all transformations applied from * the root to the Gadget itself. If this flag is * not specified, the rectangle returned will be in * logical coordinates. * </table> * </param> * * <return type="BOOL"> Rectangle was successfully retreived.</> * <see type="function"> SetGadgetRect</> * <see type="function"> GetGadgetRotation</> * <see type="function"> SetGadgetRotation</> * <see type="function"> GetGadgetScale</> * <see type="function"> SetGadgetScale</> * \***************************************************************************/
DUSER_API BOOL WINAPI GetGadgetRect( IN HGADGET hgad, // Handle of Gadget
OUT RECT * prcPxl, // Rectangle in specified pixels
IN UINT nFlags) // Rectangle to retrieve
{ DuVisual * pgad;
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_FLAGS(nFlags, SGR_VALID_GET); VALIDATE_VISUAL(gad); VALIDATE_WRITE_PTR_(prcPxl, sizeof(RECT));
if (TestFlag(nFlags, SGR_ACTUAL)) { AssertMsg(0, "TODO: Not Implemented"); } else { pgad->GetLogRect(prcPxl, nFlags); retval = TRUE; }
END_RECV(); }
/***************************************************************************\
* * SetGadgetRect (API) * * SetGadgetRect() changes the size or position of a given Gadget. * * <param name=nFlags> * nFlags can be a combination of the following flags: * <table item="Value" desc="Meaning"> * SGR_MOVE Move to Gadget to a new location specified by * x, y. * SGR_SIZE Change the Gadget's size to width w and height h. * SGR_CLIENT Coordinates are relative to the Gadget itself. * SGR_PARENT Coordinates are relative to the Gadget's parent. * SGR_CONTAINER Coordinates are relative to the Gadget's root * container. * SGR_DESKTOP Coordinates are relative to the Windows desktop. * SGR_OFFSET Coordinates are relative to the Gadget's current * location. * SGR_ACTUAL Return the bounding rectangle of the Gadget. If * this flag is specified, a bounding box is * computed from all transformations applied from * the root to the Gadget itself. If this flag is * not specified, the rectangle returned will be in * logical coordinates. * </table> * </param> * * <return type="BOOL"> Rectangle was successfully retreived.</> * <see type="function"> SetGadgetRect</> * <see type="function"> GetGadgetRotation</> * <see type="function"> SetGadgetRotation</> * <see type="function"> GetGadgetScale</> * <see type="function"> SetGadgetScale</> * \***************************************************************************/
DUSER_API BOOL WINAPI SetGadgetRect( IN HGADGET hgadChange, // Gadget to change
IN int x, // New horizontal position
IN int y, // New vertical position
IN int w, // New width
IN int h, // New height
IN UINT nFlags) // Flags specifying what to change
{ DuVisual * pgadChange; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_FLAGS(nFlags, SGR_VALID_SET); VALIDATE_VISUAL(gadChange); CHECK_MODIFY();
if (pgadChange->IsRoot()) { if (TestFlag(nFlags, SGR_MOVE)) { PromptInvalid("Can not move a RootGadget"); SetError(E_INVALIDARG); goto ErrorExit; } }
//
// Ensure that size is non-negative
//
if (TestFlag(nFlags, SGR_SIZE)) { if (w < 0) { w = 0; } if (h < 0) { h = 0; } }
if (TestFlag(nFlags, SGR_ACTUAL)) { // AssertMsg(0, "TODO: Not Implemented");
ClearFlag(nFlags, SGR_ACTUAL); hr = pgadChange->xdSetLogRect(x, y, w, h, nFlags); } else { hr = pgadChange->xdSetLogRect(x, y, w, h, nFlags); } SET_RETURN(hr, TRUE);
END_RECV(); }
/***************************************************************************\
* * FindGadgetFromPoint (API) * * FindGadgetFromPoint() determines which Gadget a contains the specified * point. * * <return type="HGADGET"> Gadget containing point or NULL for none.</> * \***************************************************************************/
DUSER_API HGADGET WINAPI FindGadgetFromPoint( IN HGADGET hgad, // Gadget to search from
IN POINT ptContainerPxl, // Point to search from in container pixels
IN UINT nStyle, // Required style flags
OUT POINT * pptClientPxl) // Optional translated point in client pixels.
{ DuVisual * pgad;
BEGIN_RECV(HGADGET, NULL, ContextLock::edNone); VALIDATE_FLAGS(nStyle, GS_VALID); VALIDATE_VISUAL(gad); VALIDATE_WRITE_PTR_OR_NULL_(pptClientPxl, sizeof(POINT));
retval = (HGADGET) GetHandle(pgad->FindFromPoint(ptContainerPxl, nStyle, pptClientPxl));
END_RECV(); }
/***************************************************************************\
* * MapGadgetPoints (API) * * MapGadgetPoints() converts a set of points in client-pixels relative to * one Gadget into points in client-pixels relative to another Gadget. * * <return type="HGADGET"> Gadget containing point or NULL for none.</> * \***************************************************************************/
DUSER_API BOOL WINAPI MapGadgetPoints( IN HGADGET hgadFrom, IN HGADGET hgadTo, IN OUT POINT * rgptClientPxl, IN int cPts) { DuVisual * pgadFrom, * pgadTo;
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_VISUAL(gadFrom); VALIDATE_VISUAL(gadTo); VALIDATE_WRITE_PTR_(rgptClientPxl, sizeof(POINT) * cPts);
if (pgadFrom->GetRoot() != pgadTo->GetRoot()) { PromptInvalid("Must be in the same tree"); SetError(E_INVALIDARG); goto ErrorExit; }
DuVisual::MapPoints(pgadFrom, pgadTo, rgptClientPxl, cPts); retval = TRUE;
END_RECV(); }
/***************************************************************************\
* * SetGadgetOrder (API) * * SetGadgetOrder() changes the Gadget's z-order relative to its siblings. * The parent of the Gadget is not changed. * * <param name=nFlags> * nFlags can be a combination of the following flags: * <table item="Value" desc="Meaning"> * GORDER_ANY The order does not matter. * GORDER_BEFORE Move this gadget in-front of sibling hgadOther. * GORDER_BEHIND Move this gadget behind sibling hgadOther. * GORDER_TOP Move this gadget to front of sibling z-order. * GORDER_BOTTOM Move this gadget to bottom of sibling z-order. * GORDER_FORWARD Move this gadget forward in sibling z-order. * GORDER_BACKWARD Move this gadget backward in sibling z-order. * </table> * </param> * * <return type="BOOL"> Gadget z-order was successfully changed.</> * <see type="function"> SetGadgetParent</> * \***************************************************************************/
DUSER_API BOOL WINAPI SetGadgetOrder( IN HGADGET hgadMove, // Gadget to be moved
IN HGADGET hgadOther, // Gadget to moved relative to
IN UINT nCmd) // Type of move
{ DuVisual * pgadMove; DuVisual * pgadOther; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_RANGE(nCmd, GORDER_MIN, GORDER_MAX); VALIDATE_VISUAL(gadMove); VALIDATE_VISUAL_OR_NULL(gadOther); CHECK_MODIFY();
hr = pgadMove->xdSetOrder(pgadOther, nCmd); SET_RETURN(hr, TRUE);
END_RECV(); }
/***************************************************************************\
* * SetGadgetParent (API) * * SetGadgetParent() changes the Gadget's parent. * * <param name=nFlags> * nFlags can be a combination of the following flags: * <table item="Value" desc="Meaning"> * GORDER_ANY The order does not matter. * GORDER_BEFORE Move this gadget in-front of sibling hgadOther. * GORDER_BEHIND Move this gadget behind sibling hgadOther. * GORDER_TOP Move this gadget to front of sibling z-order. * GORDER_BOTTOM Move this gadget to bottom of sibling z-order. * GORDER_FORWARD Move this gadget forward in sibling z-order. * GORDER_BACKWARD Move this gadget backward in sibling z-order. * </table> * </param> * * <return type="BOOL"> Gadget parent and z-order were successfully changed.</> * <see type="function"> SetGadgetOrder</> * <see type="function"> GetGadget</> * \***************************************************************************/
DUSER_API BOOL WINAPI SetGadgetParent( IN HGADGET hgadMove, // Gadget to be moved
IN HGADGET hgadParent, // New parent
IN HGADGET hgadOther, // Gadget to moved relative to
IN UINT nCmd) // Type of move
{ DuVisual * pgadMove; DuVisual * pgadParent; DuVisual * pgadOther; HRESULT hr;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_RANGE(nCmd, GORDER_MIN, GORDER_MAX); VALIDATE_VISUAL(gadMove); VALIDATE_VISUAL_OR_NULL(gadParent); VALIDATE_VISUAL_OR_NULL(gadOther); CHECK_MODIFY();
if (pgadMove->IsRoot()) { PromptInvalid("Can not change a RootGadget's parent"); SetError(E_INVALIDARG); goto ErrorExit; }
//
// Check that can become a child of the specified parent
//
if ((!pgadMove->IsRelative()) && pgadParent->IsRelative()) { PromptInvalid("Can not set non-relative child to a relative parent"); SetError(DU_E_BADCOORDINATEMAP); goto ErrorExit; }
//
// DuVisual::xdSetParent() handles if pgadParent is NULL and will move to the
// parking window.
//
hr = pgadMove->xdSetParent(pgadParent, pgadOther, nCmd); SET_RETURN(hr, TRUE);
END_RECV(); }
/***************************************************************************\
* * GetGadget (API) * * GetGadget() retrieves the Gadget that has the specified relationship to * the specified Gadget. * * <param name=nFlags> * nFlags can be a combination of the following flags: * <table item="Value" desc="Meaning"> * GG_PARENT Return the parent of the specified Gadget. * GG_NEXT Return the next sibling behind the specified * Gadget. * GG_PREV Return the previous sibling before the * specified Gadget. * GG_TOPCHILD Return the Gadget's top z-ordered child. * GG_BOTTOMCHILD Return the Gadget's bottom z-ordered child. * </table> * </param> * * <return type="BOOL"> Related Gadget or NULL for none.</> * <see type="function"> SetGadgetOrder</> * <see type="function"> SetGadgetParent</> * \***************************************************************************/
DUSER_API HGADGET WINAPI GetGadget( IN HGADGET hgad, // Handle of Gadget
IN UINT nCmd) // Relationship
{ DuVisual * pgad;
BEGIN_RECV(HGADGET, NULL, ContextLock::edNone); VALIDATE_VISUAL(gad); VALIDATE_RANGE(nCmd, GG_MIN, GG_MAX);
retval = (HGADGET) GetHandle(pgad->GetGadget(nCmd));
END_RECV(); }
/***************************************************************************\
* * InvalidateGadget (API) * * InvalidateGadget() marks a Gadget to be repainted during the next painting * cycle. * * <return type="BOOL"> Gadget was successfully invalidated.</> * <see type="message"> GM_PAINT</> * \***************************************************************************/
DUSER_API BOOL WINAPI InvalidateGadget( IN HGADGET hgad) // Gadget to repaint
{ DuVisual * pgad;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_VISUAL(gad); CHECK_MODIFY();
pgad->Invalidate(); retval = TRUE;
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API UINT WINAPI GetGadgetMessageFilter(HGADGET hgad, void * pvCookie) { DuEventGadget * pgad;
BEGIN_RECV(UINT, 0, ContextLock::edNone); VALIDATE_EVENTGADGET(gad); VALIDATE_VALUE(pvCookie, NULL);
retval = (pgad->GetFilter() & GMFI_VALID);
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI SetGadgetMessageFilter(HGADGET hgadChange, void * pvCookie, UINT nNewFilter, UINT nMask) { DuEventGadget * pgadChange;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_EVENTGADGET(gadChange); VALIDATE_FLAGS(nNewFilter, GMFI_VALID); VALIDATE_VALUE(pvCookie, NULL); CHECK_MODIFY();
pgadChange->SetFilter(nNewFilter, nMask); retval = TRUE;
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI ForwardGadgetMessage(HGADGET hgadRoot, UINT nMsg, WPARAM wParam, LPARAM lParam, LRESULT * pr) { DuVisual * pgadRoot;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_VISUAL(gadRoot); VALIDATE_WRITE_PTR(pr); CHECK_MODIFY();
retval = GdForwardMessage(pgadRoot, nMsg, wParam, lParam, pr);
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI DrawGadgetTree(HGADGET hgadDraw, HDC hdcDraw, const RECT * prcDraw, UINT nFlags) { DuVisual * pgadDraw;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_VISUAL(gadDraw); VALIDATE_READ_PTR_OR_NULL_(prcDraw, sizeof(RECT)); VALIDATE_FLAGS(nFlags, GDRAW_VALID);
retval = GdxrDrawGadgetTree(pgadDraw, hdcDraw, prcDraw, nFlags);
END_RECV(); }
/***************************************************************************\
***************************************************************************** * * DirectUser GADGET API * * <package name="Msg"/> * ***************************************************************************** \***************************************************************************/
/***************************************************************************\
* * DUserRegisterGuts * * DUserRegisterGuts() registers the implementation of a MsgClass. * \***************************************************************************/
DUSER_API HCLASS WINAPI DUserRegisterGuts( IN OUT DUser::MessageClassGuts * pmcInfo) // Class information
{ MsgClass * pmcNew; HRESULT hr;
BEGIN_RECV_NOCONTEXT(HCLASS, NULL); VALIDATE_WRITE_STRUCT(pmcInfo, DUser::MessageClassGuts);
hr = GetClassLibrary()->RegisterGutsNL(pmcInfo, &pmcNew); SET_RETURN(hr, (HCLASS) GetHandle(pmcNew));
END_RECV_NOCONTEXT(); }
/***************************************************************************\
* * DUserRegisterStub * * DUserRegisterStub() registers a Stub for a MsgClass * \***************************************************************************/
DUSER_API HCLASS WINAPI DUserRegisterStub( IN OUT DUser::MessageClassStub * pmcInfo) // Class information
{ MsgClass * pmcFind; HRESULT hr;
BEGIN_RECV_NOCONTEXT(HCLASS, NULL); VALIDATE_WRITE_STRUCT(pmcInfo, DUser::MessageClassStub);
hr = GetClassLibrary()->RegisterStubNL(pmcInfo, &pmcFind); SET_RETURN(hr, (HCLASS) GetHandle(pmcFind));
END_RECV_NOCONTEXT(); }
/***************************************************************************\
* * DUserRegisterSuper * * DUserRegisterSuper() registers a Super for a MsgClass * \***************************************************************************/
DUSER_API HCLASS WINAPI DUserRegisterSuper( IN OUT DUser::MessageClassSuper * pmcInfo) // Class information
{ MsgClass * pmcFind; HRESULT hr;
BEGIN_RECV_NOCONTEXT(HCLASS, NULL); VALIDATE_WRITE_STRUCT(pmcInfo, DUser::MessageClassSuper);
hr = GetClassLibrary()->RegisterSuperNL(pmcInfo, &pmcFind); SET_RETURN(hr, (HCLASS) GetHandle(pmcFind));
END_RECV_NOCONTEXT(); }
/***************************************************************************\
* * DUserFindClass * * DUserFindClass() finds a previously registered Gadget Class * \***************************************************************************/
DUSER_API HCLASS WINAPI DUserFindClass( IN LPCWSTR pszName, IN DWORD nVersion) { const MsgClass * pmcFind = NULL; ATOM atom; HRESULT hr;
BEGIN_RECV_NOCONTEXT(HCLASS, NULL); VALIDATE_VALUE(nVersion, 1); // Currently, all classes are version 1
atom = FindAtomW(pszName); if (atom == 0) { hr = DU_E_NOTFOUND; } else { pmcFind = GetClassLibrary()->FindClass(atom); hr = S_OK; } SET_RETURN(hr, (HCLASS) GetHandle(pmcFind));
END_RECV_NOCONTEXT(); }
/***************************************************************************\
* * DUserBuildGadget * * DUserBuildGadget() creates a fully initialized Gadget using the specified * MsgClass. * \***************************************************************************/
DUSER_API DUser::Gadget * WINAPI DUserBuildGadget( IN HCLASS hcl, // Class to construct
IN DUser::Gadget::ConstructInfo * pciData) // Construction data
{ MsgClass * pmc = ValidateMsgClass(hcl); if (pmc == NULL) { return NULL; }
MsgObject * pmoNew; HRESULT hr = pmc->xwBuildObject(&pmoNew, pciData); if (FAILED(hr)) { return NULL; }
return pmoNew->GetGadget(); }
//------------------------------------------------------------------------------
DUSER_API BOOL WINAPI DUserInstanceOf(DUser::Gadget * pg, HCLASS hclTest) { MsgObject * pmo; MsgClass * pmcTest;
pmo = MsgObject::CastMsgObject(pg); if (pmo == NULL) { PromptInvalid("The specified Gadget is invalid"); goto Error; }
pmcTest = ValidateMsgClass(hclTest); if (pmcTest == NULL) { PromptInvalid("The specified class is invalid"); goto Error; }
return pmo->InstanceOf(pmcTest);
Error: SetError(E_INVALIDARG); return FALSE; }
//------------------------------------------------------------------------------
DUSER_API DUser::Gadget * WINAPI DUserCastClass(DUser::Gadget * pg, HCLASS hclTest) { MsgObject * pmo; MsgClass * pmcTest;
//
// A NULL MsgObject is a valid input, so return NULL.
//
pmo = MsgObject::CastMsgObject(pg); if (pmo == NULL) { return NULL; }
//
// The HCLASS must be valid.
//
pmcTest = ValidateMsgClass(hclTest); if (pmcTest == NULL) { PromptInvalid("The specified class is invalid"); goto Error; }
return pmo->CastClass(pmcTest);
Error: SetError(E_INVALIDARG); return NULL; }
//------------------------------------------------------------------------------
DUSER_API DUser::Gadget * WINAPI DUserCastDirect(HGADGET hgad) { return MsgObject::CastGadget(hgad); }
//------------------------------------------------------------------------------
DUSER_API HGADGET WINAPI DUserCastHandle(DUser::Gadget * pg) { return MsgObject::CastHandle(pg); }
//------------------------------------------------------------------------------
DUSER_API void * WINAPI DUserGetGutsData(DUser::Gadget * pg, HCLASS hclData) { MsgObject * pmo; MsgClass * pmcData;
pmo = MsgObject::CastMsgObject(pg); if (pmo == NULL) { PromptInvalid("The specified Gadget is invalid"); goto Error; }
pmcData = ValidateMsgClass(hclData); if (pmcData == NULL) { PromptInvalid("The specified class is invalid"); goto Error; }
return pmo->GetGutsData(pmcData);
Error: SetError(E_INVALIDARG); return NULL; }
/***************************************************************************\
***************************************************************************** * * DirectUser GADGET API * * <package name="Lava"/> * ***************************************************************************** \***************************************************************************/
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI AttachWndProcA(HWND hwnd, ATTACHWNDPROC pfn, void * pvThis) { HRESULT hr = GdAttachWndProc(hwnd, pfn, pvThis, TRUE); if (SUCCEEDED(hr)) { return TRUE; } else { SetError(hr); return FALSE; } }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI AttachWndProcW(HWND hwnd, ATTACHWNDPROC pfn, void * pvThis) { HRESULT hr = GdAttachWndProc(hwnd, pfn, pvThis, FALSE); if (SUCCEEDED(hr)) { return TRUE; } else { SetError(hr); return FALSE; } }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI DetachWndProc(HWND hwnd, ATTACHWNDPROC pfn, void * pvThis) { HRESULT hr = GdDetachWndProc(hwnd, pfn, pvThis); if (SUCCEEDED(hr)) { return TRUE; } else { SetError(hr); return FALSE; } }
/***************************************************************************\
***************************************************************************** * * DirectUser MOTION API * * <package name="Motion"/> * ***************************************************************************** \***************************************************************************/
//---------------------------------------------------------------------------
DUSER_API HTRANSITION WINAPI CreateTransition(const GTX_TRXDESC * ptx) { BEGIN_RECV(HTRANSITION, NULL, ContextLock::edDefer); VALIDATE_READ_PTR_(ptx, sizeof(GTX_TRXDESC)); CHECK_MODIFY();
retval = (HTRANSITION) GetHandle(GdCreateTransition(ptx));
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI PlayTransition(HTRANSITION htrx, const GTX_PLAY * pgx) { Transition * ptrx;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_TRANSITION(trx); VALIDATE_READ_PTR_(pgx, sizeof(GTX_PLAY)); VALIDATE_FLAGS(pgx->nFlags, GTX_EXEC_VALID);
retval = ptrx->Play(pgx);
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI GetTransitionInterface(HTRANSITION htrx, IUnknown ** ppUnk) { Transition * ptrx;
BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_TRANSITION(trx); VALIDATE_WRITE_PTR(ppUnk);
retval = ptrx->GetInterface(ppUnk);
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI BeginTransition(HTRANSITION htrx, const GTX_PLAY * pgx) { Transition * ptrx;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_TRANSITION(trx); VALIDATE_READ_PTR_(pgx, sizeof(GTX_PLAY));
retval = ptrx->Begin(pgx);
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI PrintTransition(HTRANSITION htrx, float fProgress) { Transition * ptrx;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_TRANSITION(trx);
retval = ptrx->Print(fProgress);
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI EndTransition(HTRANSITION htrx, const GTX_PLAY * pgx) { Transition * ptrx;
BEGIN_RECV(BOOL, FALSE, ContextLock::edDefer); VALIDATE_TRANSITION(trx); VALIDATE_READ_PTR_(pgx, sizeof(GTX_PLAY));
retval = ptrx->End(pgx);
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API HACTION WINAPI CreateAction(const GMA_ACTION * pma) { BEGIN_RECV(HACTION, NULL, ContextLock::edNone); VALIDATE_READ_STRUCT(pma, GMA_ACTION);
retval = GdCreateAction(pma);
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI GetActionTimeslice(DWORD * pdwTimeslice) { BEGIN_RECV(BOOL, FALSE, ContextLock::edNone); VALIDATE_WRITE_PTR(pdwTimeslice);
*pdwTimeslice = GetMotionSC()->GetTimeslice(); retval = TRUE;
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI SetActionTimeslice(DWORD dwTimeslice) { BEGIN_RECV(BOOL, FALSE, ContextLock::edNone);
GetMotionSC()->SetTimeslice(dwTimeslice); retval = TRUE;
END_RECV(); }
/***************************************************************************\
***************************************************************************** * * DirectUser UTIL API * * <package name="Util"/> * ***************************************************************************** \***************************************************************************/
//---------------------------------------------------------------------------
DUSER_API COLORREF WINAPI GetStdColorI(UINT c) { BEGIN_RECV_NOCONTEXT(COLORREF, RGB(0, 0, 0)); VALIDATE_RANGE(c, 0, SC_MAXCOLORS);
retval = GdGetColorInfo(c)->GetColorI();
END_RECV_NOCONTEXT(); }
//---------------------------------------------------------------------------
DUSER_API Gdiplus::Color WINAPI GetStdColorF(UINT c) { BEGIN_RECV_NOCONTEXT(Gdiplus::Color, Gdiplus::Color((Gdiplus::ARGB) Gdiplus::Color::Black)); VALIDATE_RANGE(c, 0, SC_MAXCOLORS);
retval = GdGetColorInfo(c)->GetColorF();
END_RECV_NOCONTEXT(); }
//---------------------------------------------------------------------------
DUSER_API HBRUSH WINAPI GetStdColorBrushI(UINT c) { BEGIN_RECV(HBRUSH, NULL, ContextLock::edNone); VALIDATE_RANGE(c, 0, SC_MAXCOLORS);
retval = GetMotionSC()->GetBrushI(c);
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API Gdiplus::Brush * WINAPI GetStdColorBrushF(UINT c) { BEGIN_RECV(Gdiplus::Brush *, NULL, ContextLock::edNone); VALIDATE_RANGE(c, 0, SC_MAXCOLORS);
retval = GetMotionSC()->GetBrushF(c);
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API HPEN WINAPI GetStdColorPenI(UINT c) { BEGIN_RECV(HPEN, NULL, ContextLock::edNone); VALIDATE_RANGE(c, 0, SC_MAXCOLORS);
retval = GetMotionSC()->GetPenI(c);
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API Gdiplus::Pen * WINAPI GetStdColorPenF(UINT c) { BEGIN_RECV(Gdiplus::Pen *, NULL, ContextLock::edNone); VALIDATE_RANGE(c, 0, SC_MAXCOLORS);
retval = GetMotionSC()->GetPenF(c);
END_RECV(); }
//---------------------------------------------------------------------------
DUSER_API LPCWSTR WINAPI GetStdColorName(UINT c) { BEGIN_RECV_NOCONTEXT(LPCWSTR, NULL); VALIDATE_RANGE(c, 0, SC_MAXCOLORS);
retval = GdGetColorInfo(c)->GetName();
END_RECV_NOCONTEXT(); }
//---------------------------------------------------------------------------
DUSER_API UINT WINAPI FindStdColor(LPCWSTR pszName) { BEGIN_RECV_NOCONTEXT(UINT, SC_Black); VALIDATE_STRINGW_PTR(pszName, 50);
retval = GdFindStdColor(pszName);
END_RECV_NOCONTEXT(); }
//---------------------------------------------------------------------------
DUSER_API HPALETTE WINAPI GetStdPalette() { BEGIN_RECV_NOCONTEXT(HPALETTE, NULL);
retval = GdGetStdPalette();
END_RECV_NOCONTEXT(); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI UtilSetBackground(HGADGET hgadChange, HBRUSH hbrBack) { BOOL fSuccess = FALSE;
if (SetGadgetFillI(hgadChange, hbrBack, BLEND_OPAQUE, 0, 0)) { UINT nStyle = hbrBack != NULL ? GS_OPAQUE : 0; fSuccess = SetGadgetStyle(hgadChange, nStyle, GS_OPAQUE); }
return fSuccess; }
//---------------------------------------------------------------------------
DUSER_API HFONT WINAPI UtilBuildFont(LPCWSTR pszName, int idxDeciSize, DWORD nFlags, HDC hdcDevice) { return GdBuildFont(pszName, idxDeciSize, nFlags, hdcDevice); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI UtilDrawBlendRect(HDC hdcDest, const RECT * prcDest, HBRUSH hbrFill, BYTE bAlpha, int wBrush, int hBrush) { return GdDrawBlendRect(hdcDest, prcDest, hbrFill, bAlpha, wBrush, hBrush); }
//---------------------------------------------------------------------------
DUSER_API BOOL WINAPI UtilDrawOutlineRect(HDC hdc, const RECT * prcPxl, HBRUSH hbrDraw, int nThickness) { return GdDrawOutlineRect(hdc, prcPxl, hbrDraw, nThickness); }
//---------------------------------------------------------------------------
DUSER_API COLORREF WINAPI UtilGetColor(HBITMAP hbmp, POINT * pptPxl) { return GdGetColor(hbmp, pptPxl); }
/***************************************************************************\
* * GetGadgetTicket * * The GetGadgetTicket function returns the ticket that can be used to * identify the specified gadget. * * <param name="hgad"> * A handle to the gadget to retrieve the ticket for. * </param> * * <return type="DWORD"> * If the function succeeds, the return value is a 32-bit ticket that * can be used to identify the specified gadget. * If the function fails, the return value is zero. * </return> * * <remarks> * Tickets are created to give an external identity to a gadget. A * is guaranteed to be 32 bits on all platforms. If no ticket is * currently associated with this gadget, one is allocated. * </remarks> * * <see type="function">LookupGadgetTicket</> * \***************************************************************************/
DUSER_API DWORD WINAPI GetGadgetTicket( IN HGADGET hgad) // Handle of Gadget
{ DuVisual * pgad; DWORD dwTicket; HRESULT hr;
BEGIN_RECV(DWORD, 0, ContextLock::edNone); VALIDATE_VISUAL(gad);
hr = pgad->GetTicket(&dwTicket); SET_RETURN(hr, dwTicket);
END_RECV(); }
/***************************************************************************\
* * LookupGadgetTicket * * The LookupGadgetTicket function returns the gadget that is associated with * the specified ticket. * * <param name="dwTicket"> * A ticket that has been associated with a gadget via the * GetGadgetTicket function. * </param> * * <return type="HGADGET"> * If the function succeeds, the return value is a handle to the gadget * associated with the ticket. * If the function fails, the return value is NULL. * </return> * * <see type="function">GetGadgetTicket</> * \***************************************************************************/
DUSER_API HGADGET WINAPI LookupGadgetTicket( IN DWORD dwTicket) // Ticket
{ BEGIN_RECV(HGADGET, NULL, ContextLock::edNone);
retval = DuVisual::LookupTicket(dwTicket);
END_RECV(); }
|