summaryrefslogtreecommitdiffabout
path: root/shared-code/BellsNWhistles.h
blob: 1de77aecbdd5ba8ad355d10f73033fc204cbef5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#ifndef	__BELLSNWHISTLES_H
#define __BELLSNWHISTLES_H

class CBellsNWhistles	{
public:
	class CBang {
	public:
		CString m_codeName;
		enum	_bangType {
			bangNone, bangSpeaker, bangSystem, bangResource,
			bangWaveform
		}	m_type;
		BOOL m_bLoop;
		union	{
			UINT system;
			LPCTSTR resource;
			LPCTSTR wave;

			LPCTSTR str;
			UINT id;
		};
		CString m_strWave;
		CBang() : m_type(bangNone), m_bLoop(FALSE) {}
	};
	typedef CTypedPtrMap<CMapStringToPtr,CString,CBang*> CBangs;
	struct	CBelling {
		LPCSTR snd;
		HMODULE hm;
		DWORD flags;
		CBelling(LPCSTR snd,HMODULE hm,DWORD flags) : snd(snd), hm(hm),
			flags(flags) {}
		CBelling(CBelling& s) : snd(s.snd), hm(s.hm), flags(s.flags) {}
		CBelling& operator=(CBelling& s) {
			snd=s.snd; hm=s.hm; flags=s.flags;
			return *this;
		}
	};
	typedef CBelling* Whistling;

	CBangs m_bangs;

	~CBellsNWhistles() {
	POSITION p = m_bangs.GetStartPosition();
		while(p){
		CString s; CBang* b;
			m_bangs.GetNextAssoc(p,s,b);
			delete b;
		}
		m_bangs.RemoveAll();
	}

	BOOL AssignSound(LPCTSTR codeName,LPCTSTR id,CBang::_bangType type=CBang::bangWaveform) {
	CString cn = codeName;
		cn.MakeLower();
	CBang* b;
		if(!m_bangs.Lookup(cn,b)) {
			b = new CBang;
			b->m_codeName=cn;
			m_bangs[cn]=b;
		}
		b->m_type=type;
		b->str = id;
		if(type==CBang::bangWaveform){
			b->m_strWave=id; b->str = b->m_strWave;
		}
		return TRUE;
	}
	BOOL AssignSound(LPCTSTR codeName,UINT nID,CBang::_bangType type=CBang::bangResource) {
	CString cn = codeName;
		cn.MakeLower();
	CBang* b;
		if(!m_bangs.Lookup(cn,b)) {
			b = new CBang;
			b->m_codeName=cn;
			m_bangs[cn]=b;
		}
		b->m_type=type;
		b->id = nID;
		ASSERT(type!=CBang::bangWaveform);
		return TRUE;
	}
	BOOL UnassignSound(LPCTSTR codeName) {
	CString cn = codeName;
		cn.MakeLower();
	CBang* b;
		if(m_bangs.Lookup(cn,b)) {
			m_bangs.RemoveKey(cn);
			delete b;
			return TRUE;
		}
		return FALSE;
	}

	Whistling StartSound(LPCTSTR codeName) {
	Whistling* rv = NULL;
	CString cn = codeName;
	CBang* b;
		if(!m_bangs.Lookup(cn,b)){
			::PlaySound(cn,AfxGetInstanceHandle(),SND_ASYNC|SND_NODEFAULT|SND_NOWAIT|SND_FILENAME);
			return NULL;
		}
	UINT flags = SND_ASYNC|SND_NODEFAULT|SND_NOWAIT;
	LPCSTR snd = NULL;
		switch(b->m_type){
		case CBang::bangNone: return NULL;
		case CBang::bangSpeaker: MessageBeep(0xFFFFFFFF); return NULL;
		case CBang::bangSystem: MessageBeep(b->system); return NULL;
		case CBang::bangResource:
			snd = b->resource;
			flags|=SND_RESOURCE; break;
		case CBang::bangWaveform:
			snd = b->wave;
			flags|=SND_FILENAME; break;
#ifdef _DEBUG
		default:
			ASSERT(FALSE); return NULL;
#endif
		}
		if(b->m_bLoop)
			flags|=SND_LOOP;
	HMODULE hm = AfxGetInstanceHandle();
		if(!::PlaySound(snd,hm,flags))
			return NULL;
		return b->m_bLoop?new CBelling(snd,hm,flags):NULL;
	}
	BOOL StopSound(Whistling whistle) {
		if(!whistle)
			return FALSE;
		::PlaySound(whistle->snd,whistle->hm,whistle->flags|SND_PURGE);
		delete whistle;
		return TRUE;
	}
	UINT FillInCombo(CComboBox* combo) {
	POSITION p = m_bangs.GetStartPosition();
	UINT rv = 0;
		while(p) {
		CString s;
		CBang* b;
			m_bangs.GetNextAssoc(p,s,b);
			combo->AddString(s);
		}
		return rv;
	}
};

#endif	// _BELLSNWHISTLES_H