Initial commit: ROW Client source code
Game client codebase including: - CharacterActionControl: Character and creature management - GlobalScript: Network, items, skills, quests, utilities - RYLClient: Main client application with GUI and event handlers - Engine: 3D rendering engine (RYLGL) - MemoryManager: Custom memory allocation - Library: Third-party dependencies (DirectX, boost, etc.) - Tools: Development utilities 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,867 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: MapperDlg.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - an MFC based C++ filter mapper application.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
// MapperDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Mapper.h"
|
||||
#include "MapperDlg.h"
|
||||
|
||||
#include "types.h"
|
||||
#include "wxdebug.h"
|
||||
#include "fil_data.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
// ID for unpublished filter data helper method
|
||||
const IID IID_IAMFilterData = {0x97f7c4d4,0x547b,0x4a5f,{0x83,0x32,0x53,0x64,0x30,0xad,0x2e,0x4d}};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAboutDlg dialog used for App About
|
||||
|
||||
class CAboutDlg : public CDialog
|
||||
{
|
||||
public:
|
||||
CAboutDlg();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CAboutDlg)
|
||||
enum { IDD = IDD_ABOUTBOX };
|
||||
//}}AFX_DATA
|
||||
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CAboutDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
//{{AFX_MSG(CAboutDlg)
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CAboutDlg)
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CAboutDlg)
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CAboutDlg)
|
||||
// No message handlers
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMapperDlg dialog
|
||||
|
||||
CMapperDlg::CMapperDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CMapperDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CMapperDlg)
|
||||
//}}AFX_DATA_INIT
|
||||
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
|
||||
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
||||
}
|
||||
|
||||
void CMapperDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CMapperDlg)
|
||||
DDX_Control(pDX, IDC_BUTTON_SEARCH, m_bSearch);
|
||||
DDX_Control(pDX, IDC_BUTTON_CLEAR, m_bClear);
|
||||
DDX_Control(pDX, IDC_STATIC_NUMFILTERS, m_StrNumFilters);
|
||||
DDX_Control(pDX, IDC_CHECK_RENDERER, m_bIsRenderer);
|
||||
DDX_Control(pDX, IDC_CHECK_OUTPUT_PIN, m_bAtLeastOneOutputPin);
|
||||
DDX_Control(pDX, IDC_CHECK_INPUT_PIN, m_bAtLeastOneInputPin);
|
||||
DDX_Control(pDX, IDC_CHECK_EXACT_MATCH, m_bExactMatch);
|
||||
DDX_Control(pDX, IDC_LIST_OUTPUT_MINOR2, m_ListOutputMinor2);
|
||||
DDX_Control(pDX, IDC_LIST_OUTPUT_MINOR, m_ListOutputMinor);
|
||||
DDX_Control(pDX, IDC_LIST_OUTPUT_MAJOR2, m_ListOutputMajor2);
|
||||
DDX_Control(pDX, IDC_LIST_OUTPUT_MAJOR, m_ListOutputMajor);
|
||||
DDX_Control(pDX, IDC_LIST_INPUT_MINOR2, m_ListInputMinor2);
|
||||
DDX_Control(pDX, IDC_LIST_INPUT_MINOR, m_ListInputMinor);
|
||||
DDX_Control(pDX, IDC_LIST_INPUT_MAJOR2, m_ListInputMajor2);
|
||||
DDX_Control(pDX, IDC_LIST_INPUT_MAJOR, m_ListInputMajor);
|
||||
DDX_Control(pDX, IDC_COMBO_MERIT, m_ComboMerit);
|
||||
DDX_Control(pDX, IDC_COMBO_OUTPUT_CATEGORY, m_ComboOutputCat);
|
||||
DDX_Control(pDX, IDC_COMBO_INPUT_CATEGORY, m_ComboInputCat);
|
||||
DDX_Control(pDX, IDC_LIST_FILTERS, m_ListFilters);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CMapperDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CMapperDlg)
|
||||
ON_WM_SYSCOMMAND()
|
||||
ON_WM_PAINT()
|
||||
ON_WM_QUERYDRAGICON()
|
||||
ON_WM_CLOSE()
|
||||
ON_WM_DESTROY()
|
||||
ON_BN_CLICKED(IDC_BUTTON_SEARCH, OnButtonSearch)
|
||||
ON_LBN_SELCHANGE(IDC_LIST_INPUT_MAJOR, OnSelchangeListInputMajor)
|
||||
ON_LBN_SELCHANGE(IDC_LIST_OUTPUT_MAJOR, OnSelchangeListOutputMajor)
|
||||
ON_LBN_SELCHANGE(IDC_LIST_INPUT_MAJOR2, OnSelchangeListInputMajor2)
|
||||
ON_LBN_SELCHANGE(IDC_LIST_OUTPUT_MAJOR2, OnSelchangeListOutputMajor2)
|
||||
ON_BN_CLICKED(IDC_BUTTON_CLEAR, OnButtonClear)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMapperDlg message handlers
|
||||
|
||||
void CMapperDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
||||
{
|
||||
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
|
||||
{
|
||||
CAboutDlg dlgAbout;
|
||||
dlgAbout.DoModal();
|
||||
}
|
||||
else
|
||||
{
|
||||
CDialog::OnSysCommand(nID, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
// If you add a minimize button to your dialog, you will need the code below
|
||||
// to draw the icon. For MFC applications using the document/view model,
|
||||
// this is automatically done for you by the framework.
|
||||
|
||||
void CMapperDlg::OnPaint()
|
||||
{
|
||||
if (IsIconic())
|
||||
{
|
||||
CPaintDC dc(this); // device context for painting
|
||||
|
||||
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
|
||||
|
||||
// Center icon in client rectangle
|
||||
int cxIcon = GetSystemMetrics(SM_CXICON);
|
||||
int cyIcon = GetSystemMetrics(SM_CYICON);
|
||||
CRect rect;
|
||||
GetClientRect(&rect);
|
||||
int x = (rect.Width() - cxIcon + 1) / 2;
|
||||
int y = (rect.Height() - cyIcon + 1) / 2;
|
||||
|
||||
// Draw the icon
|
||||
dc.DrawIcon(x, y, m_hIcon);
|
||||
}
|
||||
else
|
||||
{
|
||||
CDialog::OnPaint();
|
||||
}
|
||||
}
|
||||
|
||||
// The system calls this to obtain the cursor to display while the user drags
|
||||
// the minimized window.
|
||||
HCURSOR CMapperDlg::OnQueryDragIcon()
|
||||
{
|
||||
return (HCURSOR) m_hIcon;
|
||||
}
|
||||
|
||||
|
||||
BOOL CMapperDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// Add "About..." menu item to system menu.
|
||||
|
||||
// IDM_ABOUTBOX must be in the system command range.
|
||||
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
|
||||
ASSERT(IDM_ABOUTBOX < 0xF000);
|
||||
|
||||
CMenu* pSysMenu = GetSystemMenu(FALSE);
|
||||
if (pSysMenu != NULL)
|
||||
{
|
||||
CString strAboutMenu;
|
||||
strAboutMenu.LoadString(IDS_ABOUTBOX);
|
||||
if (!strAboutMenu.IsEmpty())
|
||||
{
|
||||
pSysMenu->AppendMenu(MF_SEPARATOR);
|
||||
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the icon for this dialog. The framework does this automatically
|
||||
// when the application's main window is not a dialog
|
||||
SetIcon(m_hIcon, TRUE); // Set big icon
|
||||
SetIcon(m_hIcon, FALSE); // Set small icon
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DirectShow initialization code
|
||||
|
||||
CoInitialize(NULL);
|
||||
|
||||
// Create the filter mapper that will be used for all queries
|
||||
HRESULT hr = CoCreateInstance(CLSID_FilterMapper2,
|
||||
NULL, CLSCTX_INPROC, IID_IFilterMapper2,
|
||||
(void **) &m_pMapper);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
if (FAILED(hr))
|
||||
return FALSE;
|
||||
|
||||
// Initialize some application settings
|
||||
InitializeTooltips();
|
||||
SetDefaults();
|
||||
|
||||
// Customize list box tab stops for good formatting
|
||||
int nTabStops[2]={140,230};
|
||||
m_ListFilters.SetTabStops(2, nTabStops);
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
}
|
||||
|
||||
BOOL CMapperDlg::InitializeTooltips()
|
||||
{
|
||||
int rc;
|
||||
|
||||
// Create the tooltip control
|
||||
m_pToolTip = new CToolTipCtrl;
|
||||
if(!m_pToolTip->Create(this))
|
||||
{
|
||||
TRACE(TEXT("Unable To create ToolTip\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Set some tooltip defaults
|
||||
m_pToolTip->SetMaxTipWidth(250);
|
||||
m_pToolTip->SetDelayTime(TTDT_AUTOPOP, 10000); /* 10s */
|
||||
m_pToolTip->SetDelayTime(TTDT_INITIAL, 2000); /* 2s */
|
||||
|
||||
// Add tooltip strings for the relevant controls
|
||||
rc = m_pToolTip->AddTool(&m_bExactMatch, TTSTR_EXACT_MATCH);
|
||||
rc = m_pToolTip->AddTool(&m_bAtLeastOneInputPin, TTSTR_ALOIP);
|
||||
rc = m_pToolTip->AddTool(&m_bAtLeastOneOutputPin, TTSTR_ALOOP);
|
||||
rc = m_pToolTip->AddTool(&m_bIsRenderer, TTSTR_IS_RENDERER);
|
||||
rc = m_pToolTip->AddTool(&m_bClear, TTSTR_CLEAR);
|
||||
rc = m_pToolTip->AddTool(&m_bSearch, TTSTR_SEARCH);
|
||||
rc = m_pToolTip->AddTool(&m_ListFilters, TTSTR_FILTERS);
|
||||
rc = m_pToolTip->AddTool(&m_ComboMerit, TTSTR_MERIT);
|
||||
rc = m_pToolTip->AddTool(&m_ComboInputCat, TTSTR_PIN_CAT);
|
||||
rc = m_pToolTip->AddTool(&m_ComboOutputCat, TTSTR_PIN_CAT);
|
||||
rc = m_pToolTip->AddTool(&m_ListInputMajor, TTSTR_TYPE);
|
||||
rc = m_pToolTip->AddTool(&m_ListInputMajor2, TTSTR_TYPE);
|
||||
rc = m_pToolTip->AddTool(&m_ListOutputMajor, TTSTR_TYPE);
|
||||
rc = m_pToolTip->AddTool(&m_ListOutputMajor2, TTSTR_TYPE);
|
||||
rc = m_pToolTip->AddTool(&m_ListInputMinor, TTSTR_SUBTYPE);
|
||||
rc = m_pToolTip->AddTool(&m_ListInputMinor2, TTSTR_SUBTYPE);
|
||||
rc = m_pToolTip->AddTool(&m_ListOutputMinor, TTSTR_SUBTYPE);
|
||||
rc = m_pToolTip->AddTool(&m_ListOutputMinor2, TTSTR_SUBTYPE);
|
||||
|
||||
// Activate the tooltip control
|
||||
m_pToolTip->Activate(TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CMapperDlg::PreTranslateMessage(MSG* pMsg)
|
||||
{
|
||||
// Let the tooltip process the message, if appropriate
|
||||
if (m_pToolTip)
|
||||
m_pToolTip->RelayEvent(pMsg);
|
||||
|
||||
return CDialog::PreTranslateMessage(pMsg);
|
||||
}
|
||||
|
||||
void CMapperDlg::SetDefaults()
|
||||
{
|
||||
int i;
|
||||
|
||||
// The app allows you to specify up to two major/minor type pairs
|
||||
FillMajorTypes(m_ListInputMajor);
|
||||
FillMajorTypes(m_ListInputMajor2);
|
||||
FillMajorTypes(m_ListOutputMajor);
|
||||
FillMajorTypes(m_ListOutputMajor2);
|
||||
|
||||
// Initialize subtype list boxes
|
||||
m_ListInputMinor.ResetContent();
|
||||
m_ListInputMinor2.ResetContent();
|
||||
m_ListOutputMinor.ResetContent();
|
||||
m_ListOutputMinor2.ResetContent();
|
||||
|
||||
// Set checkboxes to preferred default values
|
||||
m_bAtLeastOneInputPin.SetCheck(1);
|
||||
m_bAtLeastOneOutputPin.SetCheck(1);
|
||||
|
||||
// Initialize merit box
|
||||
m_ComboMerit.ResetContent();
|
||||
for (i=0; i < NUM_MERIT_TYPES; i++)
|
||||
{
|
||||
m_ComboMerit.InsertString(i, merittypes[i].szName);
|
||||
m_ComboMerit.SetItemData(i, merittypes[i].dwMerit);
|
||||
}
|
||||
m_ComboMerit.SetCurSel(4); // "Normal" merit
|
||||
|
||||
// Initialize pin categories
|
||||
m_ComboInputCat.ResetContent();
|
||||
m_ComboOutputCat.ResetContent();
|
||||
m_ComboInputCat.AddString(TEXT("<Don't care>\0"));
|
||||
m_ComboOutputCat.AddString(TEXT("<Don't care>\0"));
|
||||
|
||||
// Fill pin category lists
|
||||
for (i=1; i < NUM_PIN_TYPES; i++)
|
||||
{
|
||||
m_ComboInputCat.InsertString(i, pintypes[i].szName);
|
||||
m_ComboInputCat.SetItemDataPtr(i, (void *) pintypes[i].pGUID);
|
||||
m_ComboOutputCat.InsertString(i, pintypes[i].szName);
|
||||
m_ComboOutputCat.SetItemDataPtr(i, (void *) pintypes[i].pGUID);
|
||||
}
|
||||
m_ComboInputCat.SetCurSel(0);
|
||||
m_ComboOutputCat.SetCurSel(0);
|
||||
|
||||
// Clear filter list
|
||||
m_ListFilters.ResetContent();
|
||||
m_StrNumFilters.SetWindowText(TEXT("Filters Matching Query : 0"));
|
||||
|
||||
// Select the first item in each type list
|
||||
FillSubType(m_ListInputMajor, m_ListInputMinor);
|
||||
FillSubType(m_ListInputMajor2, m_ListInputMinor2);
|
||||
FillSubType(m_ListOutputMajor, m_ListOutputMinor);
|
||||
FillSubType(m_ListOutputMajor2, m_ListOutputMinor2);
|
||||
|
||||
// Disable the second type/subtype listboxes until the user selects
|
||||
// something other than "don't care" for the first type/subtype pair.
|
||||
OnSelchangeListInputMajor();
|
||||
OnSelchangeListOutputMajor();
|
||||
}
|
||||
|
||||
void CMapperDlg::OnButtonClear()
|
||||
{
|
||||
// Clear all values and reset dialog
|
||||
SetDefaults();
|
||||
}
|
||||
|
||||
void CMapperDlg::OnClose()
|
||||
{
|
||||
// Disable and destroy the tooltip control
|
||||
if (m_pToolTip)
|
||||
{
|
||||
m_pToolTip->Activate(FALSE);
|
||||
delete m_pToolTip;
|
||||
m_pToolTip = 0;
|
||||
}
|
||||
|
||||
// Release FilterMapper interface
|
||||
SAFE_RELEASE(m_pMapper);
|
||||
|
||||
// Release COM
|
||||
CoUninitialize();
|
||||
|
||||
CDialog::OnClose();
|
||||
}
|
||||
|
||||
void CMapperDlg::OnDestroy()
|
||||
{
|
||||
// Disable and destroy the tooltip control
|
||||
if (m_pToolTip)
|
||||
{
|
||||
delete m_pToolTip;
|
||||
m_pToolTip = 0;
|
||||
}
|
||||
|
||||
// Release FilterMapper interface
|
||||
SAFE_RELEASE(m_pMapper);
|
||||
|
||||
CDialog::OnDestroy();
|
||||
}
|
||||
|
||||
void CMapperDlg::FillMajorTypes(CListBox& m_List)
|
||||
{
|
||||
m_List.ResetContent();
|
||||
|
||||
// Fill the specified list box with major type name/GUID
|
||||
for (int i=0; i < NUM_MAJOR_TYPES; i++)
|
||||
{
|
||||
m_List.InsertString(i, majortypes[i].szName);
|
||||
m_List.SetItemDataPtr(i, (void *) majortypes[i].pGUID);
|
||||
}
|
||||
|
||||
m_List.SetCurSel(0);
|
||||
}
|
||||
|
||||
void CMapperDlg::FillSubType(CListBox& m_List, CListBox& m_ListMinor)
|
||||
{
|
||||
const GUIDINFO *pSubtype;
|
||||
int nSelection = m_List.GetCurSel();
|
||||
int nMajorType;
|
||||
|
||||
// First clear the subtype list
|
||||
m_ListMinor.ResetContent();
|
||||
|
||||
// If the "don't care" item was selected, clear and exit
|
||||
if (nSelection == 0)
|
||||
{
|
||||
m_ListMinor.AddString(TEXT("<No subtypes>\0"));
|
||||
m_ListMinor.SetCurSel(0);
|
||||
return;
|
||||
}
|
||||
else
|
||||
nMajorType = nSelection - 1;
|
||||
|
||||
// Determine how to fill the minor type list, based on the
|
||||
// currently selected major type.
|
||||
pSubtype = pSubTypes[nMajorType];
|
||||
|
||||
// If there's no associated subtype, just add a default
|
||||
if (!pSubtype)
|
||||
{
|
||||
m_ListMinor.AddString(TEXT("<No subtypes>\0"));
|
||||
m_ListMinor.SetCurSel(0);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set a default item for "don't care"
|
||||
m_ListMinor.AddString(TEXT("<Don't care>\0"));
|
||||
|
||||
int i=0;
|
||||
|
||||
// Fill the subtype list box. Enter N item data to the N+1 list slot.
|
||||
while (pSubtype[i].pGUID != NULL)
|
||||
{
|
||||
m_ListMinor.AddString(pSubtype[i].szName);
|
||||
m_ListMinor.SetItemDataPtr(i+1, (void *) pSubtype[i].pGUID);
|
||||
i++;
|
||||
}
|
||||
|
||||
m_ListMinor.SetCurSel(0);
|
||||
}
|
||||
}
|
||||
|
||||
void CMapperDlg::OnSelchangeListInputMajor()
|
||||
{
|
||||
// User has selected a new major type, so refill the subtype list box
|
||||
FillSubType(m_ListInputMajor, m_ListInputMinor);
|
||||
|
||||
// Since the second type/subtype pair is irrelevant if the first
|
||||
// is a don't care, disable the second set if appropriate.
|
||||
EnableSecondTypePair(m_ListInputMajor, m_ListInputMajor2, m_ListInputMinor2);
|
||||
}
|
||||
|
||||
void CMapperDlg::OnSelchangeListInputMajor2()
|
||||
{
|
||||
// User has selected a new major type, so refill the subtype list box
|
||||
FillSubType(m_ListInputMajor2, m_ListInputMinor2);
|
||||
}
|
||||
|
||||
void CMapperDlg::OnSelchangeListOutputMajor()
|
||||
{
|
||||
// User has selected a new major type, so refill the subtype list box
|
||||
FillSubType(m_ListOutputMajor, m_ListOutputMinor);
|
||||
|
||||
// Since the second type/subtype pair is irrelevant if the first
|
||||
// is a don't care, disable the second set if appropriate.
|
||||
EnableSecondTypePair(m_ListOutputMajor, m_ListOutputMajor2, m_ListOutputMinor2);
|
||||
}
|
||||
|
||||
void CMapperDlg::OnSelchangeListOutputMajor2()
|
||||
{
|
||||
// User has selected a new major type, so refill the subtype list box
|
||||
FillSubType(m_ListOutputMajor2, m_ListOutputMinor2);
|
||||
}
|
||||
|
||||
void CMapperDlg::EnableSecondTypePair(CListBox& m_ListMajor,
|
||||
CListBox& m_ListMajor2, CListBox& m_ListMinor2)
|
||||
{
|
||||
// If there is no selection in the first major type listbox,
|
||||
// clear and disable the second major/minor type listboxes.
|
||||
if (m_ListMajor.GetCurSel() == 0)
|
||||
{
|
||||
m_ListMajor2.SetCurSel(0);
|
||||
FillSubType(m_ListMajor2, m_ListMinor2);
|
||||
|
||||
m_ListMajor2.EnableWindow(FALSE);
|
||||
m_ListMinor2.EnableWindow(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ListMajor2.EnableWindow(TRUE);
|
||||
m_ListMinor2.EnableWindow(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void FillTypeArray(CListBox& m_ListMajor, CListBox& m_ListMinor,
|
||||
GUID *atypes, int nIndex, DWORD *pdwPairs)
|
||||
{
|
||||
int nMajorSel = m_ListMajor.GetCurSel();
|
||||
int nMinorSel = m_ListMinor.GetCurSel();
|
||||
|
||||
// If no selection ("don't care"), just exit without modifying the array
|
||||
if (nMajorSel <= 0)
|
||||
return;
|
||||
|
||||
// Get GUID for major type
|
||||
const GUID *p1 = (const GUID *)m_ListMajor.GetItemDataPtr(nMajorSel);
|
||||
|
||||
// Since the FilterMapper interface requires GUIDs (instead of GUID *),
|
||||
// copy the specified GUID data into its array slot.
|
||||
memcpy(&atypes[nIndex], p1, sizeof(GUID));
|
||||
|
||||
// Increment number of type/subtype pairs
|
||||
(*pdwPairs)++;
|
||||
|
||||
// If no selection ("don't care"), or uninitialized (returning -1),
|
||||
// just exit without modifying the array
|
||||
if (nMinorSel <= 0)
|
||||
return;
|
||||
|
||||
// Get GUID for subtype
|
||||
const GUID *p2 = (const GUID *)m_ListMinor.GetItemDataPtr(nMinorSel);
|
||||
|
||||
if (p2)
|
||||
memcpy(&atypes[nIndex+1], p2, sizeof(GUID));
|
||||
}
|
||||
|
||||
IEnumMoniker *CMapperDlg::GetFilterEnumerator(void)
|
||||
{
|
||||
// First set up the boolean values
|
||||
BOOL bExactMatch = m_bExactMatch.GetCheck();
|
||||
BOOL bAtLeastOneInputPin = m_bAtLeastOneInputPin.GetCheck();
|
||||
BOOL bAtLeastOneOutputPin = m_bAtLeastOneOutputPin.GetCheck();
|
||||
BOOL bIsRenderer = m_bIsRenderer.GetCheck();
|
||||
|
||||
// Merit
|
||||
DWORD dwMerit = (DWORD) m_ComboMerit.GetItemData(m_ComboMerit.GetCurSel());
|
||||
|
||||
// Pin categories
|
||||
const GUID *pInCat = (const GUID *)
|
||||
m_ComboInputCat.GetItemDataPtr(m_ComboInputCat.GetCurSel());
|
||||
const GUID *pOutCat = (const GUID *)
|
||||
m_ComboOutputCat.GetItemDataPtr(m_ComboOutputCat.GetCurSel());
|
||||
|
||||
// Major type/subtype pairs
|
||||
DWORD dwInputTypes=0, dwOutputTypes=0;
|
||||
GUID arrayInput[4], arrayOutput[4];
|
||||
|
||||
// Initialize GUID type/subtype arrays
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
arrayInput[i] = GUID_NULL;
|
||||
arrayOutput[i] = GUID_NULL;
|
||||
}
|
||||
|
||||
// Fill each of the four GUID arrays (input/output, major/minor).
|
||||
// If the first call doesn't set anything (primary), don't bother to
|
||||
// read the secondary value, since it would be invalid anyway due to
|
||||
// its position within the array (2) but with a count of only 1.
|
||||
FillTypeArray(m_ListInputMajor, m_ListInputMinor, arrayInput, 0, &dwInputTypes);
|
||||
if (dwInputTypes)
|
||||
FillTypeArray(m_ListInputMajor2, m_ListInputMinor2, arrayInput, 2, &dwInputTypes);
|
||||
|
||||
FillTypeArray(m_ListOutputMajor, m_ListOutputMinor, arrayOutput, 0, &dwOutputTypes);
|
||||
if (dwOutputTypes)
|
||||
FillTypeArray(m_ListOutputMajor2, m_ListOutputMinor2, arrayOutput, 2, &dwOutputTypes);
|
||||
|
||||
// Enumerate all filters that match the specified criteria
|
||||
IEnumMoniker *pEnum;
|
||||
HRESULT hr=S_OK;
|
||||
|
||||
hr = m_pMapper->EnumMatchingFilters(
|
||||
&pEnum,
|
||||
0, // Reserved
|
||||
bExactMatch, // Use exact match?
|
||||
dwMerit, // Minimum merit
|
||||
bAtLeastOneInputPin,
|
||||
dwInputTypes, // Number of major type/subtype pairs for input
|
||||
arrayInput, // Array of major type/subtype pairs for input
|
||||
NULL, // Input medium
|
||||
pInCat, // Input pin category
|
||||
bIsRenderer, // Must be a renderer?
|
||||
bAtLeastOneOutputPin,
|
||||
dwOutputTypes, // Number of major type/subtype pairs for output
|
||||
arrayOutput, // Array of major type/subtype pairs for output
|
||||
NULL, // Output medium
|
||||
pOutCat); // Output pin category
|
||||
|
||||
if (FAILED(hr))
|
||||
return 0;
|
||||
else
|
||||
return pEnum;
|
||||
}
|
||||
|
||||
int CMapperDlg::GetFilenameByCLSID(REFCLSID clsid, TCHAR *szFile)
|
||||
{
|
||||
HRESULT hr;
|
||||
LPOLESTR strCLSID;
|
||||
int rc=0;
|
||||
|
||||
// Convert binary CLSID to a readable version
|
||||
hr = StringFromCLSID(clsid, &strCLSID);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
TCHAR szKey[512];
|
||||
CString strQuery(strCLSID);
|
||||
|
||||
// Create key name for reading filename from registry
|
||||
wsprintf(szKey, TEXT("Software\\Classes\\CLSID\\%s\\InprocServer32\0"),
|
||||
strQuery);
|
||||
|
||||
// Free memory associated with strCLSID (allocated in StringFromCLSID)
|
||||
CoTaskMemFree(strCLSID);
|
||||
|
||||
HKEY hkeyFilter=0;
|
||||
DWORD dwSize=MAX_PATH;
|
||||
BYTE szFilename[MAX_PATH];
|
||||
|
||||
// Open the CLSID key that contains information about the filter
|
||||
rc = RegOpenKey(HKEY_LOCAL_MACHINE, szKey, &hkeyFilter);
|
||||
if (rc == ERROR_SUCCESS)
|
||||
{
|
||||
rc = RegQueryValueEx(hkeyFilter, NULL, // Read (Default) value
|
||||
NULL, NULL, szFilename, &dwSize);
|
||||
|
||||
if (rc == ERROR_SUCCESS)
|
||||
wsprintf(szFile, TEXT("%s"), szFilename);
|
||||
|
||||
RegCloseKey(hkeyFilter);
|
||||
}
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Read merit and version information
|
||||
HRESULT CMapperDlg::GetMerit(IPropertyBag *pPropBag, DWORD *pdwMerit)
|
||||
{
|
||||
HRESULT hr;
|
||||
IAMFilterData *pData=0;
|
||||
|
||||
*pdwMerit = 0;
|
||||
|
||||
VARIANT varFilData={0};
|
||||
varFilData.vt = VT_UI1 | VT_ARRAY;
|
||||
varFilData.parray = 0; // docs say to zero this
|
||||
|
||||
BYTE *pbFilterData = 0; // 0 if not read
|
||||
DWORD dwcbFilterDAta = 0; // 0 if not read
|
||||
|
||||
// Read compressed filter data from the property bag with a variant
|
||||
hr = pPropBag->Read(L"FilterData", &varFilData, 0);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
ASSERT(varFilData.vt == (VT_UI1 | VT_ARRAY));
|
||||
dwcbFilterDAta = varFilData.parray->rgsabound[0].cElements;
|
||||
|
||||
// Access the filter data
|
||||
HRESULT hrTmp = SafeArrayAccessData(varFilData.parray, (void **)&pbFilterData);
|
||||
ASSERT(hrTmp == S_OK);
|
||||
ASSERT(pbFilterData);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(dwcbFilterDAta == 0 && pbFilterData == 0);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Get the IAMFilterData interface for parsing the filter data
|
||||
hr = m_pMapper->QueryInterface(IID_IAMFilterData, (void **)&pData);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
BYTE *pb=0;
|
||||
|
||||
// Use a helper method to parse the binary filter data. Pass in
|
||||
// the pointer to the filter data, its size, and a buffer to fill with
|
||||
// the resulting data. The "pb" buffer is allocated with CoTaskMemAlloc,
|
||||
// so it must be correspondingly freed by the caller.
|
||||
hr = pData->ParseFilterData(pbFilterData, dwcbFilterDAta, &pb);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
REGFILTER2 *pFil = ((REGFILTER2 **)pb)[0];
|
||||
|
||||
if(pbFilterData)
|
||||
{
|
||||
HRESULT hrTmp = SafeArrayUnaccessData(varFilData.parray);
|
||||
ASSERT(hrTmp == S_OK);
|
||||
|
||||
hrTmp = VariantClear(&varFilData);
|
||||
ASSERT(hrTmp == S_OK);
|
||||
}
|
||||
|
||||
// Assign the merit value from the REGFILTER2 structure
|
||||
if (pFil)
|
||||
*pdwMerit = pFil->dwMerit;
|
||||
|
||||
// Free the memory allocated by ParseFilterData
|
||||
if (pb)
|
||||
CoTaskMemFree(pb);
|
||||
}
|
||||
|
||||
// Release the IAMFilterData interface
|
||||
pData->Release();
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
void CMapperDlg::AddMerit(TCHAR *szInfo, DWORD dwMerit)
|
||||
{
|
||||
TCHAR szMerit[32];
|
||||
|
||||
switch (dwMerit)
|
||||
{
|
||||
case MERIT_NORMAL:
|
||||
wsprintf(szMerit, TEXT("MERIT_NORMAL\0"));
|
||||
break; // Assume normal
|
||||
case MERIT_PREFERRED:
|
||||
wsprintf(szMerit, TEXT("MERIT_PREFERRED\0"));
|
||||
break;
|
||||
case MERIT_UNLIKELY:
|
||||
wsprintf(szMerit, TEXT("MERIT_UNLIKELY\0"));
|
||||
break;
|
||||
case MERIT_DO_NOT_USE:
|
||||
wsprintf(szMerit, TEXT("MERIT_DO_NOT_USE\0"));
|
||||
break;
|
||||
case MERIT_SW_COMPRESSOR:
|
||||
wsprintf(szMerit, TEXT("MERIT_SW_COMPRESSOR\0"));
|
||||
break;
|
||||
case MERIT_HW_COMPRESSOR:
|
||||
wsprintf(szMerit, TEXT("MERIT_HW_COMPRESSOR\0"));
|
||||
break;
|
||||
|
||||
default:
|
||||
wsprintf(szMerit, TEXT("0x%08x\0"), dwMerit);
|
||||
break;
|
||||
}
|
||||
|
||||
// Add new merit information to string
|
||||
_tcscat(szInfo, szMerit);
|
||||
}
|
||||
|
||||
|
||||
void CMapperDlg::AddFilter(const TCHAR *szFilterName, const GUID *pCatGuid, DWORD dwMerit)
|
||||
{
|
||||
TCHAR szInfo[300], szFilename[255];
|
||||
|
||||
// First add the friendly name of the filter
|
||||
wsprintf(szInfo, TEXT("%s\t\0"), szFilterName);
|
||||
|
||||
// Add the filter's merit value
|
||||
AddMerit(szInfo, dwMerit);
|
||||
|
||||
// Get the filter's server name from the registry
|
||||
int rc = GetFilenameByCLSID(*pCatGuid, szFilename);
|
||||
|
||||
// Add the filter's server name
|
||||
if (rc == ERROR_SUCCESS)
|
||||
{
|
||||
_tcscat(szInfo, TEXT("\t\0"));
|
||||
_tcscat(szInfo, szFilename);
|
||||
}
|
||||
|
||||
// Add the filter name and filename to the listbox
|
||||
m_ListFilters.AddString(szInfo);
|
||||
}
|
||||
|
||||
void CMapperDlg::OnButtonSearch()
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
IEnumMoniker *pEnum;
|
||||
IMoniker *pMoniker=0;
|
||||
ULONG cFetched=0;
|
||||
VARIANT varName={0};
|
||||
int nFilters=0;
|
||||
|
||||
// Clear any previous results
|
||||
m_ListFilters.ResetContent();
|
||||
|
||||
// Enumerate filters based on the current dialog box selections
|
||||
pEnum = GetFilterEnumerator();
|
||||
if (!pEnum)
|
||||
{
|
||||
m_ListFilters.AddString(TEXT("<No filters matched query>"));
|
||||
return;
|
||||
}
|
||||
hr = pEnum->Reset();
|
||||
|
||||
// Enumerate all filters that match the search criteria. The enumerator
|
||||
// that is returned from GetFilterEnumerator() will only list filters
|
||||
// that matched the user's search request.
|
||||
while((hr = pEnum->Next(1, &pMoniker, &cFetched)) == S_OK)
|
||||
{
|
||||
IPropertyBag *pPropBag;
|
||||
ASSERT(pMoniker);
|
||||
|
||||
// Associate the moniker with a file
|
||||
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
|
||||
(void **)&pPropBag);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
ASSERT(pPropBag);
|
||||
if (FAILED(hr))
|
||||
continue;
|
||||
|
||||
// Read filter name from property bag
|
||||
varName.vt = VT_BSTR;
|
||||
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
|
||||
if (FAILED(hr))
|
||||
continue;
|
||||
|
||||
// Get filter name (converting BSTR name to a CString)
|
||||
CString str(varName.bstrVal);
|
||||
SysFreeString(varName.bstrVal);
|
||||
nFilters++;
|
||||
|
||||
// Read Merit value from property bag
|
||||
DWORD dwMerit;
|
||||
GetMerit(pPropBag, &dwMerit);
|
||||
|
||||
// Read filter's CLSID from property bag. This CLSID string will be
|
||||
// converted to a binary CLSID and passed to AddFilter(), which will
|
||||
// add the filter's name to the listbox and its CLSID to the listbox
|
||||
// item's DataPtr item.
|
||||
VARIANT varFilterClsid;
|
||||
varFilterClsid.vt = VT_BSTR;
|
||||
|
||||
// Read CLSID string from property bag
|
||||
hr = pPropBag->Read(L"CLSID", &varFilterClsid, 0);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
CLSID clsidFilter;
|
||||
|
||||
// Add filter name and filename to listbox
|
||||
if(CLSIDFromString(varFilterClsid.bstrVal, &clsidFilter) == S_OK)
|
||||
{
|
||||
AddFilter(str, &clsidFilter, dwMerit);
|
||||
}
|
||||
|
||||
SysFreeString(varFilterClsid.bstrVal);
|
||||
}
|
||||
|
||||
// Clean up interfaces
|
||||
SAFE_RELEASE(pPropBag);
|
||||
SAFE_RELEASE(pMoniker);
|
||||
}
|
||||
|
||||
// Display number of filters matching query
|
||||
TCHAR szNumFilters[48];
|
||||
wsprintf(szNumFilters, TEXT("Filters Matching Query : %d"), nFilters);
|
||||
m_StrNumFilters.SetWindowText(szNumFilters);
|
||||
|
||||
// Clean up enumerator
|
||||
if (pEnum)
|
||||
pEnum->Release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user