299 lines
7.9 KiB
C
299 lines
7.9 KiB
C
/****************************************************************************
|
|
*
|
|
* File : multimed.c
|
|
*
|
|
* Description :
|
|
* Top level control panel applet code for multimedia for
|
|
* Windows NT
|
|
*
|
|
* Copyright (c) 1993 Microsoft Corporation
|
|
*
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
|
|
Design
|
|
|
|
This module contains the code and data (apart from the icons for
|
|
the 3 applets) to support 3 control panel applets for multi-media :
|
|
|
|
sound - Setting system sounds
|
|
|
|
midimap - Midi mapper
|
|
|
|
drivers - Installation and configuration of installable drivers through
|
|
installable drivers interface
|
|
|
|
The interface in is as for all control panel applets. This (super)
|
|
applet returns a number of internal applets to the CPL_GETCOUNT
|
|
message depending on :
|
|
|
|
waveOutGetNumDevs returns non-zero - then sound is supported.
|
|
|
|
midiOutGetNumDevs returns non-zero or midiInGetNumDevs returns
|
|
non-zero - then midimap is supported.
|
|
|
|
Interface to sub-applets. For packaging and historical reasons the
|
|
other applets are separate files :
|
|
|
|
sound - sound.dll
|
|
midimap - midimap.dll - is also a midi driver
|
|
drivers - drivers.dll
|
|
|
|
When an applet (which is supported for the current configuration of
|
|
the system as determined above) is run (and ONLY THEN) via the
|
|
CPL_DBLCLK message we call LoadLibrary for the (sub) applet and
|
|
call its entry point (usually a 'cut-down' CplApplet).
|
|
|
|
To do this each sub-applet's icon and string have fixed ids defined in
|
|
multimed.h.
|
|
|
|
*****************************************************************************/
|
|
|
|
#include <windows.h>
|
|
#include <mmsystem.h>
|
|
#include <cpl.h>
|
|
#include <cphelp.h>
|
|
#include "multimed.h"
|
|
|
|
// This applet has been neutered to provide only MIDIMAP.DLL's CPL
|
|
// interface; the others are now supported by MMSYS.CPL.
|
|
//
|
|
// #define EXTRA_APPLETS
|
|
#ifdef EXTRA_APPLETS
|
|
enum {
|
|
SoundsApplet = 0,
|
|
DriversApplet,
|
|
MidiMapApplet,
|
|
ACMApplet,
|
|
NumberOfApplets
|
|
};
|
|
|
|
struct {
|
|
LPCTSTR AppletFileName;
|
|
DWORD dwHelpContext;
|
|
HINSTANCE ActiveHandle;
|
|
APPLET_PROC AppletEntryPoint;
|
|
BOOL AppInUse;
|
|
NEWCPLINFO CplInfo;
|
|
}
|
|
AppletInfo[] = { { TEXT("sound.dll"), IDH_CHILD_SND },
|
|
{ TEXT("drivers.dll"), IDH_CHILD_DRIVERS },
|
|
{ TEXT("midimap.dll"), IDH_CHILD_MIDI },
|
|
{ TEXT("msacm32.drv"), 0 } }; // No context for ACM
|
|
#else
|
|
enum {
|
|
MidiMapApplet = 0,
|
|
NumberOfApplets
|
|
};
|
|
|
|
struct {
|
|
LPCTSTR AppletFileName;
|
|
DWORD dwHelpContext;
|
|
HINSTANCE ActiveHandle;
|
|
APPLET_PROC AppletEntryPoint;
|
|
BOOL AppInUse;
|
|
NEWCPLINFO CplInfo;
|
|
}
|
|
AppletInfo[] = { { TEXT("midimap.dll"), IDH_CHILD_MIDI } };
|
|
#endif
|
|
|
|
|
|
int IdMapping[NumberOfApplets];
|
|
int TotalApplets;
|
|
|
|
BOOL LoadDataPart(int AppletIndex)
|
|
{
|
|
UINT OldErrorMode;
|
|
LPNEWCPLINFO lpCplInfo;
|
|
HINSTANCE DataOnlyHandle;
|
|
|
|
OldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
|
|
|
DataOnlyHandle =
|
|
LoadLibraryEx(AppletInfo[AppletIndex].AppletFileName,
|
|
NULL,
|
|
DONT_RESOLVE_DLL_REFERENCES);
|
|
|
|
SetErrorMode(OldErrorMode);
|
|
|
|
if (DataOnlyHandle == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* Cache all Cpl data now so we're not embarrassed by errors later
|
|
*/
|
|
|
|
lpCplInfo = &AppletInfo[AppletIndex].CplInfo;
|
|
|
|
lpCplInfo->dwSize = sizeof(NEWCPLINFO);
|
|
lpCplInfo->lData = 0; // Applets we use expect this
|
|
lpCplInfo->dwHelpContext = AppletInfo[AppletIndex].dwHelpContext;
|
|
lpCplInfo->hIcon =
|
|
LoadIcon(DataOnlyHandle,
|
|
MAKEINTRESOURCE(ID_ICON));
|
|
|
|
if (lpCplInfo->hIcon == NULL ||
|
|
!LoadString(DataOnlyHandle,
|
|
IDS_NAME,
|
|
lpCplInfo->szName,
|
|
sizeof(lpCplInfo->szName)) ||
|
|
!LoadString(DataOnlyHandle,
|
|
IDS_INFO,
|
|
lpCplInfo->szInfo,
|
|
sizeof(lpCplInfo->szInfo)) ||
|
|
!LoadString(DataOnlyHandle,
|
|
IDS_CONTROL_HLP,
|
|
lpCplInfo->szHelpFile,
|
|
sizeof(lpCplInfo->szHelpFile))) {
|
|
|
|
FreeLibrary(DataOnlyHandle);
|
|
return FALSE;
|
|
}
|
|
|
|
FreeLibrary(DataOnlyHandle);
|
|
return TRUE;
|
|
}
|
|
|
|
LONG CPlApplet(HWND hCplWnd, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
|
|
{
|
|
LONG ReturnCode = 0L; // The default apparently
|
|
int i;
|
|
|
|
switch (uMsg) {
|
|
case CPL_INIT:
|
|
|
|
/*
|
|
* I've no idea why this is a better place to initialize than
|
|
* CPL_GETCOUNT but why not?
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* Check there's somebody home
|
|
*/
|
|
|
|
for (i = 0; i < NumberOfApplets; i++) {
|
|
|
|
/*
|
|
** Don't put up useless junk!
|
|
*/
|
|
|
|
if (i == MidiMapApplet && midiOutGetNumDevs() == 0
|
|
#ifdef EXTRA_APPLETS
|
|
|| i == ACMApplet && waveOutGetNumDevs() == 0
|
|
#endif
|
|
)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (LoadDataPart(i)) {
|
|
IdMapping[TotalApplets++] = i;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Only succeed if we support something
|
|
*/
|
|
|
|
ReturnCode = TotalApplets != 0;
|
|
|
|
break;
|
|
|
|
case CPL_GETCOUNT:
|
|
return TotalApplets;
|
|
break;
|
|
|
|
case CPL_NEWINQUIRE:
|
|
{
|
|
LPNEWCPLINFO lpCplInfo;
|
|
int iApplet;
|
|
|
|
iApplet = IdMapping[lParam1];
|
|
|
|
lpCplInfo = (LPNEWCPLINFO)lParam2;
|
|
|
|
*lpCplInfo = AppletInfo[iApplet].CplInfo;
|
|
}
|
|
|
|
break;
|
|
|
|
case CPL_DBLCLK:
|
|
|
|
/*
|
|
* The job here is to
|
|
* 1. If the applet is not already loaded
|
|
* -- load it
|
|
* -- Pass it a cpl_init message - this will do for our applets(!)
|
|
*
|
|
* 2. Pass it a CPL_DBLCLK message with the parameters we got
|
|
*
|
|
*/
|
|
{
|
|
int iApplet;
|
|
|
|
iApplet = IdMapping[lParam1];
|
|
|
|
|
|
if (AppletInfo[iApplet].ActiveHandle == NULL) {
|
|
|
|
UINT OldErrorMode;
|
|
|
|
OldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
|
|
|
AppletInfo[iApplet].ActiveHandle =
|
|
LoadLibrary(AppletInfo[iApplet].AppletFileName);
|
|
|
|
SetErrorMode(OldErrorMode);
|
|
|
|
if (AppletInfo[iApplet].ActiveHandle != NULL) {
|
|
AppletInfo[iApplet].AppletEntryPoint =
|
|
(APPLET_PROC)GetProcAddress(
|
|
AppletInfo[iApplet].ActiveHandle,
|
|
"CPlApplet");
|
|
}
|
|
if (AppletInfo[iApplet].AppletEntryPoint != NULL) {
|
|
(*AppletInfo[iApplet].AppletEntryPoint)
|
|
(hCplWnd, CPL_INIT, 0, 0);
|
|
}
|
|
}
|
|
|
|
if (AppletInfo[iApplet].AppletEntryPoint != NULL) {
|
|
(*AppletInfo[iApplet].AppletEntryPoint)
|
|
(hCplWnd, uMsg, lParam1, lParam2);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case CPL_EXIT:
|
|
|
|
/*
|
|
* Unload all our friends
|
|
*/
|
|
|
|
|
|
{
|
|
int i;
|
|
for (i = 0; i < NumberOfApplets; i++) {
|
|
|
|
if (AppletInfo[i].ActiveHandle != NULL) {
|
|
if (AppletInfo[i].AppletEntryPoint != NULL) {
|
|
(*AppletInfo[i].AppletEntryPoint)
|
|
(hCplWnd, CPL_EXIT, 0, 0);
|
|
}
|
|
FreeLibrary(AppletInfo[i].ActiveHandle);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return ReturnCode;
|
|
}
|