299 lines
7.6 KiB
C
299 lines
7.6 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;
|
||
|
}
|