📄 events.cpp
字号:
/*
* EVENTS.CPP
* Patron Chapter 24
*
* Implementation of the Events dialog box, the CEventMap class,
* and the events IDispatch on a tenant control site.
*
* Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Microsoft
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "patron.h"
/*
* EventsDlgProc
*
* Purpose:
* Dialog procedure for the dialog in which the user can assign
* actions to events.
*/
BOOL APIENTRY EventsDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam
, LPARAM lParam)
{
PCEventMap pEM=NULL;
HWND hList;
UINT i, iEvent;
COMMANDPARAMS(wID, wCode, hWndMsg);
#ifdef WIN32
pEM=(PCEventMap)GetProp(hDlg, PROP_POINTER);
#else
WORD w1, w2;
w1=(WORD)GetProp(hDlg, PROP_SELECTOR);
w2=(WORD)GetProp(hDlg, PROP_OFFSET);
pEM=(PCEventMap)MAKELP(w1, w2);
#endif
switch (iMsg)
{
case WM_INITDIALOG:
pEM=(PCEventMap)lParam;
#ifdef WIN32
SetProp(hDlg, PROP_POINTER, (HANDLE)pEM);
#else
SetProp(hDlg, PROP_SELECTOR, (HANDLE)SELECTOROF(pEM));
SetProp(hDlg, PROP_OFFSET, (HANDLE)OFFSETOF(pEM));
#endif
/*
* Fill the listbox with events and select the first
* one. The selection will cause an LBN_SELCHANGE
* notification which will set the appropriate
* radiobutton for the action.
*/
hList=GetDlgItem(hDlg, IDC_EVENTLIST);
for (i=0; i < pEM->m_cEvents; i++)
{
//Add the name of the event to the list
#ifdef WIN32ANSI
char szTemp[40];
WideCharToMultiByte(CP_ACP, 0
, pEM->m_pEventMap[i].bstrName, -1, szTemp
, 40, NULL, NULL);
iEvent=(UINT)SendMessage(hList, LB_ADDSTRING, 0
, (LONG)(LPSTR)szTemp);
#else
iEvent=(UINT)SendMessage(hList, LB_ADDSTRING, 0
, (LONG)(LPSTR)pEM->m_pEventMap[i].bstrName);
#endif
if (LB_ERR!=iEvent)
{
//Give that item a pointer to the map data
SendMessage(hList, LB_SETITEMDATA, iEvent
, (LONG)&pEM->m_pEventMap[i]);
}
}
//Set the initial action for the first item
SendMessage(hList, LB_SETCURSEL, 0, 0L);
CheckAction(hDlg, hList);
return TRUE;
case WM_COMMAND:
hList=GetDlgItem(hDlg, IDC_EVENTLIST);
switch (wID)
{
case IDOK:
EndDialog(hDlg, 1);
break;
case ID_TEST:
TestSelection(hList);
break;
case IDC_EVENTLIST:
//Update the radiobuttons
if (LBN_SELCHANGE==wCode)
CheckAction(hDlg, hWndMsg);
//Double-click, same as hitting Test button
if (LBN_DBLCLK==wCode)
TestSelection(GetDlgItem(hDlg, IDC_EVENTLIST));
break;
case IDC_BEEPNONE:
case IDC_BEEPDEFAULT:
case IDC_BEEPEXCLAMATION:
case IDC_BEEPASTERISK:
case IDC_BEEPHAND:
case IDC_BEEPQUESTION:
UpdateAction(hList, wID);
break;
}
return TRUE;
}
return FALSE;
}
/*
* CheckAction
*
* Purpose:
* Sets the appropriate radiobutton for the current listbox
* selection
*
* Parameters:
* hDlg HWND of the dialog.
* hList HWND of the event list.
*
* Return Value:
* None
*/
void CheckAction(HWND hDlg, HWND hList)
{
UINT i, idControl;
PEVENTMAP pMap;
i=(UINT)SendMessage(hList, LB_GETCURSEL, 0, 0L);
pMap=(PEVENTMAP)SendMessage(hList, LB_GETITEMDATA, i, 0L);
if (LB_ERR==(LONG)pMap)
return;
//Map the action to the button
switch (pMap->iAction)
{
case ACTION_NONE: idControl=IDC_BEEPNONE; break;
case ACTION_BEEPDEFAULT: idControl=IDC_BEEPDEFAULT; break;
case ACTION_BEEPASTERISK: idControl=IDC_BEEPASTERISK; break;
case ACTION_BEEPEXCLAMATION: idControl=IDC_BEEPEXCLAMATION; break;
case ACTION_BEEPHAND: idControl=IDC_BEEPHAND; break;
case ACTION_BEEPQUESTION: idControl=IDC_BEEPQUESTION; break;
default: idControl=IDC_BEEPNONE; break;
}
CheckRadioButton(hDlg, IDC_BEEPNONE, IDC_BEEPQUESTION, idControl);
return;
}
/*
* UpdateAction
*
* Purpose:
* Sets the appropriate action in the event map for the
* selected radiobutton.
*
* Parameters:
* hList HWND of the event list.
* idControl UINT identifier of the selected action control
*
* Return Value:
* None
*/
void UpdateAction(HWND hList, UINT idControl)
{
UINT i;
PEVENTMAP pMap;
i=(UINT)SendMessage(hList, LB_GETCURSEL, 0, 0L);
pMap=(PEVENTMAP)SendMessage(hList, LB_GETITEMDATA, i, 0L);
if (LB_ERR==(LONG)pMap)
return;
//Map the button to the action
switch (idControl)
{
case IDC_BEEPNONE: pMap->iAction=ACTION_NONE; break;
case IDC_BEEPDEFAULT: pMap->iAction=ACTION_BEEPDEFAULT; break;
case IDC_BEEPASTERISK: pMap->iAction=ACTION_BEEPASTERISK; break;
case IDC_BEEPEXCLAMATION: pMap->iAction=ACTION_BEEPEXCLAMATION; break;
case IDC_BEEPHAND: pMap->iAction=ACTION_BEEPHAND; break;
case IDC_BEEPQUESTION: pMap->iAction=ACTION_BEEPQUESTION; break;
default: pMap->iAction=ACTION_NONE; break;
}
return;
}
/*
* TestSelection
*
* Purpose:
* Executes the action associated with the currently selected
* event.
*
* Parameters:
* hList HWND of the event list.
*
* Return Value:
* None
*/
void TestSelection(HWND hList)
{
UINT i;
PEVENTMAP pMap;
i=(UINT)SendMessage(hList, LB_GETCURSEL, 0, 0L);
pMap=(PEVENTMAP)SendMessage(hList, LB_GETITEMDATA, i, 0L);
//Event values corresond to MessageBeep values.
if (LB_ERR!=(LONG)pMap)
MessageBeep(pMap->iAction);
return;
}
//CEventMap implementations
/*
* CEventMap::CEventMap
* CEventMap::~CEventMap
*
* Parameters (Constructor):
* pITypeInfo LPTYPEINFO from which to read event names.
*/
CEventMap::CEventMap(LPTYPEINFO pITypeInfo)
{
m_cEvents=0;
m_pITypeInfo=pITypeInfo;
if (NULL!=m_pITypeInfo)
m_pITypeInfo->AddRef();
m_pEventMap=NULL;
return;
}
CEventMap::~CEventMap(void)
{
if (NULL!=m_pITypeInfo)
m_pITypeInfo->Release();
if (NULL!=m_pEventMap)
{
UINT i;
//Be sure to clean up allocated BSTRs
for (i=0; i < m_cEvents; i++)
SysFreeString(m_pEventMap[i].bstrName);
delete [] m_pEventMap;
}
return;
}
/*
* CEventMap::Init
*
* Purpose:
* Initializes the event map with any operation prone to failure.
* If this function fails, the caller should delete this object
* immediately as it is unusable.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if initialization succeeded, FALSE otherwise
*/
BOOL CEventMap::Init(void)
{
LPTYPEATTR pTA;
UINT i;
if (NULL==m_pITypeInfo)
return FALSE;
if (FAILED(m_pITypeInfo->GetTypeAttr(&pTA)))
return FALSE;
m_cEvents=pTA->cFuncs;
m_pITypeInfo->ReleaseTypeAttr(pTA);
m_pEventMap=new EVENTMAP[m_cEvents];
if (NULL==m_pEventMap)
{
m_cEvents=0;
return FALSE;
}
for (i=0; i < m_cEvents; i++)
{
LPFUNCDESC pFD;
m_pEventMap[i].id=0;
m_pEventMap[i].bstrName=NULL;
m_pEventMap[i].iAction=ACTION_NONE;
/*
* The only piece of information we want from for each
* event is the function name using ITypeInfo::GetNames.
*
* A more sophisticated container will probably save
* more information about each event here (such as
* parameter names and so forth) or access it dynamically
* when the end user wants to write code for events.
*/
if (SUCCEEDED(m_pITypeInfo->GetFuncDesc(i, &pFD)))
{
UINT cNames;
HRESULT hr;
/*
* Since we only want the function name, we ask
* ITypeInfo::GetNames for only one function and pass
* the address of our one BSTR to it. If we wanted all
* the names from ITypeInfo, then we'd allocate an
* array of BSTRs with "new BSTR[pFD->cParams+1]"
* and pass pFD->cParams+1 to GetNames below instead
* of just 1. In either case, GetNames allocates
* the string and stores the pointer to it in our
* variable.
*/
m_pEventMap[i].id=pFD->memid;
hr=m_pITypeInfo->GetNames(pFD->memid
, &m_pEventMap[i].bstrName, 1, &cNames);
m_pITypeInfo->ReleaseFuncDesc(pFD);
}
}
return TRUE;
}
/*
* CEventMap::Set
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -