Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
msgloop.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : Command & Conquer *
24 * *
25 * $Archive:: /Commando/Code/wwlib/msgloop.cpp $*
26 * *
27 * $Author:: Steve_t $*
28 * *
29 * $Modtime:: 2/05/02 1:17p $*
30 * *
31 * $Revision:: 2 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * Add_Accelerator -- Adds a keyboard accelerator to the message handler. *
36 * Add_Modeless_Dialog -- Adds a modeless dialog box to the message handler. *
37 * Remove_Accelerator -- Removes an accelerator from the message processor. *
38 * Remove_Modeless_Dialog -- Removes the dialog box from the message tracking handler. *
39 * Windows_Message_Handler -- Handles windows message. *
40 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
41
42#include "always.h"
43#include "vector.h"
44#include "win.h"
45
46
47/*
48** Tracks modeless dialog box messages by keeping a record of all active modeless dialog
49** box handles and then determining if the windows message applies to the dialog box. If it
50** does, then the default message handling should not be performed.
51*/
52static DynamicVectorClass<HWND> _ModelessDialogs;
53
54
55/*
56** Tracks windows accelerators with this structure.
57*/
59 AcceleratorTracker(HWND window = NULL, HACCEL accelerator = NULL) : Accelerator(accelerator), Window(window) {}
60
61 int operator == (AcceleratorTracker const & acc) const {return(Accelerator == acc.Accelerator && Window == acc.Window);}
62 int operator != (AcceleratorTracker const & acc) const {return(!(*this == acc));}
63
65 HWND Window;
66};
68
69
70/*
71** In those cases where message intercept needs to occur but not for purposes
72** of a modeless dialog box or a windows accelerator, then this is a function
73** pointer to than message intercept handler.
74*/
76
77
78/***********************************************************************************************
79 * Windows_Message_Handler -- Handles windows message. *
80 * *
81 * This routine will take all messages that have accumulated in the message queue and *
82 * dispatch them to their respective recipients. When the message queue has been emptied, *
83 * then this routine will return. By using this routine, it is possible to have the main *
84 * program run in the main thread and yet still have it behave like a normal program as *
85 * far as message handling is concerned. To achieve this, this routine must be called on *
86 * a semi-frequent basis (a few times a second is plenty). *
87 * *
88 * INPUT: none *
89 * *
90 * OUTPUT: none *
91 * *
92 * WARNINGS: none *
93 * *
94 * HISTORY: *
95 * 05/17/1997 JLB : Created. *
96 *=============================================================================================*/
98{
99 MSG msg;
100
101 /*
102 ** Process windows messages until the message queue is exhuasted.
103 */
104 while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
105 if (!GetMessage( &msg, NULL, 0, 0 )) {
106 return;
107 }
108
109 /*
110 ** Pass the message through any loaded accelerators. If the message
111 ** was processed by an accelerator, then it doesn't need to be
112 ** processed by the normal message handling procedure.
113 */
114 bool processed = false;
115 for (int aindex = 0; aindex < _Accelerators.Count(); aindex++) {
116 if (_Accelerators[aindex].Window) {
117 if (TranslateAccelerator(_Accelerators[aindex].Window, _Accelerators[aindex].Accelerator, &msg)) {
118 processed = true;
119 }
120 }
121 break;
122 }
123 if (processed) continue;
124
125 /*
126 ** Pass the windows message through any modeless dialogs that may
127 ** be active. If one of the dialogs processes the message, then
128 ** it must not be processed by the normal window message handler.
129 */
130 for (int index = 0; index < _ModelessDialogs.Count(); index++) {
131 if (IsDialogMessage(_ModelessDialogs[index], &msg)) {
132 processed = true;
133 break;
134 }
135 }
136 if (processed) continue;
137
138 /*
139 ** If the message was not handled by any normal intercept handlers, then
140 ** submit the message to a custom message handler if one has been provided.
141 */
143 processed = Message_Intercept_Handler(msg);
144 }
145 if (processed) continue;
146
147 /*
148 ** If the message makes it to this point, then it must be a normal message. Process
149 ** it in the normal fashion. The message will appear in the window message handler
150 ** for the window that it was directed to.
151 */
152 TranslateMessage(&msg);
153 DispatchMessage(&msg);
154 }
155}
156
157
158/***********************************************************************************************
159 * Add_Modeless_Dialog -- Adds a modeless dialog box to the message handler. *
160 * *
161 * When a modeless dialog box becomes active, the messages processed by the main message *
162 * handler must be handled different. This routine is used to inform the message handler *
163 * that a dialog box is active and messages must be fed to it as appropriate. *
164 * *
165 * INPUT: dialog -- Handle to the modeless dialog box. *
166 * *
167 * OUTPUT: none *
168 * *
169 * WARNINGS: The modeless dialog box must be removed from the tracking system by calling *
170 * Remove_Modeless_Dialog. Failure to do so when the dialog is destroyed will *
171 * result in undefined behavior. *
172 * *
173 * HISTORY: *
174 * 05/17/1997 JLB : Created. *
175 *=============================================================================================*/
176void Add_Modeless_Dialog(HWND dialog)
177{
178 _ModelessDialogs.Add(dialog);
179}
180
181
182/***********************************************************************************************
183 * Remove_Modeless_Dialog -- Removes the dialog box from the message tracking handler. *
184 * *
185 * This routine must be called when a modeless dialog is being removed. *
186 * *
187 * INPUT: dialog -- Handle to the modeless dialog that was previously submitted to *
188 * Add_Modeless_Dialog(). *
189 * *
190 * OUTPUT: none *
191 * *
192 * WARNINGS: Failure to call this routine will result in undefined behavior when the dialog *
193 * is destroyed. *
194 * *
195 * HISTORY: *
196 * 05/17/1997 JLB : Created. *
197 *=============================================================================================*/
198void Remove_Modeless_Dialog(HWND dialog)
199{
200 _ModelessDialogs.Delete(dialog);
201}
202
203
204/***********************************************************************************************
205 * Add_Accelerator -- Adds a keyboard accelerator to the message handler. *
206 * *
207 * This routine will add a keyboard accelerator to the tracking process for the message *
208 * handler. If the incoming message is processed by an accelerator, then the normal *
209 * processing must be altered. By using this routine, the proper behavior of accelerators *
210 * is maintained. *
211 * *
212 * INPUT: window -- The window that the accelerator belongs to. Each accelerator must be *
213 * assigned to a window. *
214 * *
215 * accelerator -- The handler to the windows accelerator. *
216 * *
217 * OUTPUT: none *
218 * *
219 * WARNINGS: When the accelerator is no longer valid (or the controlling window as been *
220 * destroyed), the Remove_Accelerator function must be called. *
221 * *
222 * HISTORY: *
223 * 05/17/1997 JLB : Created. *
224 *=============================================================================================*/
225void Add_Accelerator(HWND window, HACCEL accelerator)
226{
227 _Accelerators.Add(AcceleratorTracker(window, accelerator));
228}
229
230
231/***********************************************************************************************
232 * Remove_Accelerator -- Removes an accelerator from the message processor. *
233 * *
234 * This routine must be called when the accelerator or the window it was attached to has *
235 * been destroyed. *
236 * *
237 * INPUT: accelerator -- The accelerator to remove from the tracking system. *
238 * *
239 * OUTPUT: none *
240 * *
241 * WARNINGS: This routine presumes that the accelerator will not be shared between windows. *
242 * *
243 * HISTORY: *
244 * 05/17/1997 JLB : Created. *
245 *=============================================================================================*/
246void Remove_Accelerator(HACCEL accelerator)
247{
248 for (int index = 0; index < _Accelerators.Count(); index++) {
249 if (_Accelerators[index].Accelerator == accelerator) {
250 _Accelerators.Delete(index);
251 break;
252 }
253 }
254}
#define NULL
Definition BaseType.h:92
#define bool
Definition gimex.h:284
void Remove_Modeless_Dialog(HWND dialog)
Definition msgloop.cpp:198
void Windows_Message_Handler(void)
Definition msgloop.cpp:97
void Add_Accelerator(HWND window, HACCEL accelerator)
Definition msgloop.cpp:225
bool(* Message_Intercept_Handler)(MSG &msg)
Definition msgloop.cpp:75
void Remove_Accelerator(HACCEL accelerator)
Definition msgloop.cpp:246
void Add_Modeless_Dialog(HWND dialog)
Definition msgloop.cpp:176
MSG msg
Definition patch.cpp:409
int operator!=(AcceleratorTracker const &acc) const
Definition msgloop.cpp:62
int operator==(AcceleratorTracker const &acc) const
Definition msgloop.cpp:61
AcceleratorTracker(HWND window=NULL, HACCEL accelerator=NULL)
Definition msgloop.cpp:59