1 /* aNetHack 0.0.1 mhcmd.c $ANH-Date: 1432512800 2015/05/25 00:13:20 $ $ANH-Branch: master $:$ANH-Revision: 1.14 $ */
2 /* aNetHack may be freely redistributed. See license for details. */
10 static TCHAR szNHCmdWindowClass
[] = TEXT("MSNethackCmdWndClass");
13 #define C(c) (0x1f & (c))
17 #define NH_CST_CHECKED 1
20 #define NH_CMDPAD_FONT_NORMAL 0
21 #define NH_CMDPAD_FONT_MAX 0
23 /* type of the cell */
25 #define NH_CELL_CTRL 1
27 #define NH_CELL_SHIFT 3
28 #define NH_CELL_LAYOUT_NEW 4
29 #define NH_CELL_LAYOUT_MENU 5
31 #define NH_CMDSET_MAXSIZE 64
33 /* Keypad cell information
35 NHCmdPadCell.cell_type NHCmdPadCell.data
36 ----------- ----------
37 NH_CELL_REG (int)>=0 - index in the
38 current keypad layout set (loads a new layout)
39 -1 - restore default (saved) layout
42 NH_CELL_SHIFT not used
43 NH_CELL_LAYOUT_NEW pointer to the new keypad layout
45 NH_CELL_LAYOUT_MENU pointer to the layout set (NHCmdSet* - if
46 NULL then nhcmdset_default is used)
48 typedef struct t_NHCmdPadCell
{
49 UINT cmd_code
; /* Windows command code (menu processing - not implemented
51 char f_char
[16]; /* anethack char */
52 char text
[16]; /* display text */
53 int image
; /* >0 - image ID in IDB_KEYPAD bitmap
54 <=0 - absolute index of the font table */
55 int type
; /* cell type */
56 int mult
; /* cell width multiplier */
57 void *data
; /* internal data for the cell type */
58 } NHCmdPadCell
, *PNHCmdPadCell
;
61 typedef struct t_NHCmdLayout
{
66 } NHCmdLayout
, *PNHCmdLayout
;
68 /* set of command layouts */
69 typedef struct t_NHCmdSet
{
71 struct t_NHCmdSetElem
{
74 } elements
[NH_CMDSET_MAXSIZE
];
75 } NHCmdSet
, *PNHCmdSet
;
77 /* display cell layout */
78 typedef struct t_NHCmdPadLayoutCell
{
79 POINT orig
; /* origin of the cell rect */
80 BYTE type
; /* cell type */
81 int state
; /* cell state */
82 } NHCmdPadLayoutCell
, *PNHCmdPadLayoutCell
;
84 /* command window data */
85 typedef struct mswin_anethack_cmd_window
{
86 SIZE cell_size
; /* cell size */
87 HFONT font
[NH_CMDPAD_FONT_MAX
+ 1]; /* fonts for cell text */
88 HBITMAP images
; /* key images map */
89 int active_cell
; /* current active cell */
91 boolean is_caps
; /* is CAPS selected */
92 boolean is_ctrl
; /* is CRTL selected */
93 boolean is_shift
; /* is SHIFT selected */
95 PNHCmdLayout layout_current
; /* current layout */
96 PNHCmdLayout layout_save
; /* saved layout */
97 PNHCmdPadLayoutCell cells
; /* display cells */
99 #if defined(WIN_CE_SMARTPHONE)
100 PNHCmdLayout layout_selected
; /* since we use
102 command for menu also
103 we need to store the layout
108 } NHCmdWindow
, *PNHCmdWindow
;
110 LRESULT CALLBACK
NHCommandWndProc(HWND
, UINT
, WPARAM
, LPARAM
);
111 static void register_command_window_class();
112 static void LayoutCmdWindow(HWND hWnd
);
113 static void SetCmdWindowLayout(HWND hWnd
, PNHCmdLayout layout
);
114 static int CellFromPoint(PNHCmdWindow data
, POINT pt
);
115 static void CalculateCellSize(HWND hWnd
, LPSIZE pSize
, LPSIZE windowSize
);
116 static void HighlightCell(HWND hWnd
, int cell
, BOOL isSelected
);
117 static void ActivateCell(HWND hWnd
, int cell
);
118 static void PushNethackCommand(const char *cmd_char_str
, int is_ctrl
);
120 /*------------------- keyboard keys layout functions -----------------------*/
121 PNHCmdLayout
nhcmdlayout_create(const char *name
, int rows
, int columns
);
122 void nhcmdlayout_init(PNHCmdLayout p
, PNHCmdPadCell cells
);
123 #define nhcmdlayout_rows(p) ((p)->rows)
124 #define nhcmdlayout_columns(p) ((p)->columns)
125 #define nhcmdlayout_row(p, x) (&((p)->cells[(p)->columns * (x)]))
126 #define nhcmdlayout_cell(p, x, y) (&((p)->cells[(p)->columns * (x) + (y)]))
127 #define nhcmdlayout_cell_direct(p, i) (&((p)->cells[(i)]))
128 void nhcmdlayout_destroy(PNHCmdLayout p
);
130 /*----------------- keyboard keys layout set functions ---------------------*/
131 PNHCmdSet
nhcmdset_create();
132 int nhcmdset_count(PNHCmdSet p
);
133 PNHCmdLayout
nhcmdset_get(PNHCmdSet p
, int index
);
134 const char *nhcmdset_get_name(PNHCmdSet p
, int index
);
135 void nhcmdset_add(PNHCmdSet p
, PNHCmdLayout layout
);
136 void nhcmdset_destroy(PNHCmdSet p
);
138 /*-------------------- message handlers -----------------------------------*/
139 static void onPaint(HWND hWnd
); // on WM_PAINT
140 static void onCreate(HWND hWnd
, WPARAM wParam
, LPARAM lParam
); // on WM_CREATE
141 static void onMouseDown(HWND hWnd
, WPARAM wParam
,
142 LPARAM lParam
); // on WM_LBUTTONDOWN
143 static void onMouseMove(HWND hWnd
, WPARAM wParam
,
144 LPARAM lParam
); // on WM_MOUSEMOVE
145 static void onMouseUp(HWND hWnd
, WPARAM wParam
,
146 LPARAM lParam
); // on WM_LBUTTONUP
148 /*----------------------- static data -------------------------------------*/
149 static PNHCmdSet nhcmdset_current
= 0;
150 static PNHCmdSet nhcmdset_default
= 0;
152 /*---------------------- Pre-definde keyboard layouts --------------------*/
153 #ifdef WIN_CE_SMARTPHONE
155 /* dimensions of the command pad */
156 #define NH_CMDPAD_ROWS 4
157 #define NH_CMDPAD_COLS 3
158 #define NH_CMDPAD_CELLNUM (NH_CMDPAD_COLS * NH_CMDPAD_ROWS)
161 #define NH_LAYOUT_GENERAL 0
162 #define NH_LAYOUT_MOVEMENT 1
163 #define NH_LAYOUT_ATTACK 2
164 #define NH_LAYOUT_ITEM_HANDLING 3
165 #define NH_LAYOUT_CONTROLS 4
166 #define NH_LAYOUT_ADV_MOVEMENT 5
167 #define NH_LAYOUT_ITEM_LOOKUP 6
168 #define NH_LAYOUT_WIZARD 7
170 /* template menu layout */
171 NHCmdPadCell cells_layout_menu
[NH_CMDPAD_CELLNUM
] = {
172 { -1, "", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
173 { -1, "", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
174 { -1, "", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
175 { -1, "", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
176 { -1, "", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
177 { -1, "", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
178 { -1, "", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
179 { -1, "", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
180 { -1, "", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
181 { -1, "", "<<", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_LAYOUT_NEW
, 1, NULL
},
182 { -1, "", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
183 { -1, "", ">>", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_LAYOUT_NEW
, 1, NULL
}
186 /* movement layout */
187 NHCmdPadCell cells_layout_movement
[NH_CMDPAD_CELLNUM
] = {
188 { -1, "7", "7", 1, NH_CELL_REG
, 1, (void *) - 1 },
189 { -1, "8", "8", 2, NH_CELL_REG
, 1, (void *) - 1 },
190 { -1, "9", "9", 3, NH_CELL_REG
, 1, (void *) - 1 },
191 { -1, "4", "4", 4, NH_CELL_REG
, 1, (void *) - 1 },
192 { -1, ".", ".", 5, NH_CELL_REG
, 1, (void *) - 1 },
193 { -1, "6", "6", 6, NH_CELL_REG
, 1, (void *) - 1 },
194 { -1, "1", "1", 7, NH_CELL_REG
, 1, (void *) - 1 },
195 { -1, "2", "2", 8, NH_CELL_REG
, 1, (void *) - 1 },
196 { -1, "3", "3", 9, NH_CELL_REG
, 1, (void *) - 1 },
197 { -1, "<", "<", 10, NH_CELL_REG
, 1, (void *) - 1 },
198 { -1, ">", ">", 12, NH_CELL_REG
, 1, (void *) - 1 },
199 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU
, 1, 0 }
203 NHCmdPadCell cells_layout_attack
[NH_CMDPAD_CELLNUM
] = {
204 { -1, "t", "t", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
205 { -1, "w", "w", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
206 { -1, "x", "x", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
207 { -1, "f", "f", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
208 { -1, "z", "z", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
209 { -1, "Z", "Z", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
210 { -1, "r", "r", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
211 { -1, "a", "a", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
212 { -1, "q", "q", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
213 { -1, "\x04", "^D", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
215 { -1, "F", "F", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
216 (void *) NH_LAYOUT_MOVEMENT
},
217 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU
, 1, 0 }
220 /* item handling layout */
221 NHCmdPadCell cells_layout_item_handling
[NH_CMDPAD_CELLNUM
] = {
222 { -1, "W", "W", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
223 { -1, "P", "P", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
224 { -1, "d", "d", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
225 { -1, "T", "T", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
226 { -1, "R", "R", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
227 { -1, "D", "D", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
228 { -1, "=", "=", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
229 { -1, "i", "i", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
230 { -1, "Q", "Q", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
231 { -1, "A", "A", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
232 { -1, "I", "I", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
233 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU
, 1, 0 }
237 NHCmdPadCell cells_layout_general
[NH_CMDPAD_CELLNUM
] = {
238 { -1, "q", "q", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
239 { -1, "e", "e", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
240 { -1, "l", "l", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
241 { -1, "s", "s", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
242 { -1, "E", "E", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
243 { -1, "\x01", "^A", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
245 { -1, "c", "c", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
246 { -1, "o", "o", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
247 { -1, "p", "p", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
248 { -1, ":", ":", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
249 { -1, ",", ",", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
250 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU
, 1, 0 }
253 /* game controls layout */
254 NHCmdPadCell cells_layout_game
[NH_CMDPAD_CELLNUM
] = {
255 { -1, "S", "S", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
256 { -1, "h", "h", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
257 { -1, "C", "C", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
258 { -1, "@", "@", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
259 { -1, "\\", "\\", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
260 { -1, "O", "O", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
261 { -1, "&", "&", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
262 { -1, "\x18", "^X", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
264 { -1, "\x10", "^P", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
266 { -1, "X", "X", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
267 { -1, "#", "#", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
268 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU
, 1, 0 }
271 /* advanced movement layout */
272 NHCmdPadCell cells_layout_adv_movement
[NH_CMDPAD_CELLNUM
] = {
273 { -1, "g", "g", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
274 (void *) NH_LAYOUT_MOVEMENT
},
275 { -1, "G", "G", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
276 (void *) NH_LAYOUT_MOVEMENT
},
277 { -1, "m", "m", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
278 (void *) NH_LAYOUT_MOVEMENT
},
279 { -1, "M", "M", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
280 (void *) NH_LAYOUT_MOVEMENT
},
281 { -1, "_", "_", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
282 { -1, "\x14", "^T", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
284 { -1, "j", "j", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
285 { -1, "<", "<", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
286 { -1, ">", ">", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
287 { -1, "^", "^", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
288 { -1, "", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
289 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU
, 1, 0 }
292 /* item lookup layout */
293 NHCmdPadCell cells_layout_lookup
[NH_CMDPAD_CELLNUM
] = {
294 { -1, ";", ";", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
295 { -1, "^", "^", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
296 { -1, "]", "]", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
297 { -1, ")", ")", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
298 { -1, "=", "=", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
299 { -1, "*", "*", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
300 { -1, "(", "(", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
301 { -1, "\"", "\"", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
302 { -1, "$", "$", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
303 { -1, "+", "+", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
304 { -1, "", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
305 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU
, 1, 0 }
308 /* wizard mode layout */
309 NHCmdPadCell cells_layout_wizard
[NH_CMDPAD_CELLNUM
] = {
310 { -1, "\x05", "^e", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
312 { -1, "\x06", "^f", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
314 { -1, "\x07", "^g", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
316 { -1, "\x09", "^i", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
318 { -1, "\x0f", "^o", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
320 { -1, "\x16", "^v", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
322 { -1, "\x17", "^w", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
324 { -1, "\x14", "^T", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1,
326 { -1, "#", "#", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
327 { -1, "", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
328 { -1, "", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
329 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU
, 1, 0 }
332 #else /* !WIN_CE_SMARTPHONE */
334 /* dimensions of the command pad */
335 #define NH_CMDPAD_ROWS 4
336 #define NH_CMDPAD_COLS 14
337 #define NH_CMDPAD_CELLNUM (NH_CMDPAD_COLS * NH_CMDPAD_ROWS)
339 /* lowercase layout */
340 NHCmdPadCell cells_layout_mod1
[NH_CMDPAD_ROWS
* NH_CMDPAD_COLS
] = {
341 { -1, "7", "7", 1, NH_CELL_REG
, 1, (void *) - 1 },
342 { -1, "8", "8", 2, NH_CELL_REG
, 1, (void *) - 1 },
343 { -1, "9", "9", 3, NH_CELL_REG
, 1, (void *) - 1 },
344 { -1, "\x1b", "Esc", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 2, NULL
},
345 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 0,
346 NULL
}, /* complement for ESC */
347 { -1, "?", "?", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
348 { -1, "*", "*", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
349 { -1, ",", ",", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
350 { -1, "/", "/", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
351 { -1, ":", ":", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
352 { -1, ";", ";", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
353 { -1, "-", "-", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
354 { -1, "#", "#", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
355 { -1, "^", "^", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
357 { -1, "4", "4", 4, NH_CELL_REG
, 1, (void *) - 1 },
358 { -1, "5", "5", 5, NH_CELL_REG
, 1, (void *) - 1 },
359 { -1, "6", "6", 6, NH_CELL_REG
, 1, (void *) - 1 },
360 { -1, " ", "CAP", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_CAP
, 2, NULL
},
361 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 0,
362 NULL
}, /* complement for CAPS */
363 { -1, "a", "a", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
364 { -1, "b", "b", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
365 { -1, "c", "c", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
366 { -1, "d", "d", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
367 { -1, "e", "e", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
368 { -1, "f", "f", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
369 { -1, "g", "g", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
370 { -1, "h", "h", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
371 { -1, "i", "i", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
373 { -1, "1", "1", 7, NH_CELL_REG
, 1, (void *) - 1 },
374 { -1, "2", "2", 8, NH_CELL_REG
, 1, (void *) - 1 },
375 { -1, "3", "3", 9, NH_CELL_REG
, 1, (void *) - 1 },
376 { -1, " ", "Shft", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_SHIFT
, 2, NULL
},
377 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 0,
378 NULL
}, /* complement for shift */
379 { -1, "j", "j", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
380 { -1, "k", "k", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
381 { -1, "l", "l", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
382 { -1, "m", "m", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
383 { -1, "n", "n", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
384 { -1, "o", "o", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
385 { -1, "p", "p", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
386 { -1, "q", "q", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
387 { -1, "r", "r", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
389 { -1, "<", "<", 10, NH_CELL_REG
, 1, (void *) - 1 },
390 { -1, ".", ".", 11, NH_CELL_REG
, 1, (void *) - 1 },
391 { -1, ">", ">", 12, NH_CELL_REG
, 1, (void *) - 1 },
392 { -1, " ", "Ctrl", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_CTRL
, 2, NULL
},
393 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 0,
394 NULL
}, /* complement for CTRL */
395 { -1, "s", "s", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
396 { -1, "t", "t", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
397 { -1, "u", "u", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
398 { -1, "v", "v", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
399 { -1, "w", "w", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
400 { -1, "x", "x", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
401 { -1, "y", "y", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
402 { -1, "z", "z", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
403 { -1, "\\", "\\", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 }
406 /* uppercase layout */
407 NHCmdPadCell cells_layout_mod2
[-NH_CMDPAD_ROWS
* -NH_CMDPAD_COLS
] = {
408 { -1, "7", "7", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
409 { -1, "8", "8", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
410 { -1, "9", "9", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
411 { -1, "\x1b", "Esc", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 2, NULL
},
412 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 0,
413 NULL
}, /* complement for ESC */
414 { -1, "?", "?", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
415 { -1, "*", "*", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
416 { -1, "[", "[", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
417 { -1, "(", "(", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
418 { -1, ")", ")", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
419 { -1, "+", "+", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
420 { -1, "=", "=", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
421 { -1, "\"", "\"", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
422 { -1, "$", "$", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
424 { -1, "4", "4", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
425 { -1, "5", "5", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
426 { -1, "6", "6", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
427 { -1, " ", "CAP", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_CAP
, 2, NULL
},
428 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 0,
429 NULL
}, /* complement for CAPS */
430 { -1, "A", "A", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
431 { -1, "B", "B", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
432 { -1, "C", "C", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
433 { -1, "D", "D", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
434 { -1, "E", "E", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
435 { -1, "F", "F", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
436 { -1, "G", "G", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
437 { -1, "H", "H", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
438 { -1, "I", "I", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
440 { -1, "1", "1", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
441 { -1, "2", "2", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
442 { -1, "3", "3", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
443 { -1, " ", "Shft", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_SHIFT
, 2, NULL
},
444 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 0,
445 NULL
}, /* complement for shift */
446 { -1, "J", "J", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
447 { -1, "K", "K", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
448 { -1, "L", "L", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
449 { -1, "M", "M", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
450 { -1, "N", "N", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
451 { -1, "O", "O", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
452 { -1, "P", "P", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
453 { -1, "Q", "Q", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
454 { -1, "R", "R", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
456 { -1, "<", "<", 10, NH_CELL_REG
, 1, (void *) - 1 },
457 { -1, "0", "0", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
458 { -1, ">", ">", 12, NH_CELL_REG
, 1, (void *) - 1 },
459 { -1, " ", "Ctrl", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_CTRL
, 2, NULL
},
460 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 0,
461 NULL
}, /* complement for CTRL */
462 { -1, "S", "S", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
463 { -1, "T", "T", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
464 { -1, "U", "U", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
465 { -1, "V", "V", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
466 { -1, "W", "W", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
467 { -1, "X", "X", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
468 { -1, "Y", "Y", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
469 { -1, "Z", "Z", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 },
470 { -1, "@", "@", -NH_CMDPAD_FONT_NORMAL
, NH_CELL_REG
, 1, (void *) - 1 }
473 #endif /* !WIN_CE_SMARTPHONE */
475 /*-------------------------------------------------------------------------*/
477 mswin_init_command_window()
479 static int run_once
= 0;
482 /* register window class */
484 register_command_window_class();
490 szNHCmdWindowClass
, /* registered class name */
491 NULL
, /* window name */
492 WS_CHILD
| WS_CLIPSIBLINGS
, /* window style */
493 0, /* horizontal position of window - set it later */
494 0, /* vertical position of window - set it later */
495 0, /* window width - set it later */
496 0, /* window height - set it later*/
497 GetNHApp()->hMainWnd
, /* handle to parent or owner window */
498 NULL
, /* menu handle or child identifier */
499 GetNHApp()->hApp
, /* handle to application instance */
500 NULL
); /* window-creation data */
502 panic("Cannot create command window");
506 /*-------------------------------------------------------------------------*/
507 /* calculate mimimum window size */
509 mswin_command_window_size(HWND hwnd
, LPSIZE sz
)
513 data
= (PNHCmdWindow
) GetWindowLong(hwnd
, GWL_USERDATA
);
517 CalculateCellSize(hwnd
, &cell_size
, sz
);
518 sz
->cx
= max(cell_size
.cx
* nhcmdlayout_columns(data
->layout_current
)
519 + 2 * GetSystemMetrics(SM_CXBORDER
),
521 sz
->cy
= max(cell_size
.cy
* nhcmdlayout_rows(data
->layout_current
)
522 + 2 * GetSystemMetrics(SM_CYBORDER
),
526 /*-------------------------------------------------------------------------*/
528 register_command_window_class()
532 ZeroMemory(&wcex
, sizeof(wcex
));
535 wcex
.style
= CS_NOCLOSE
;
536 wcex
.lpfnWndProc
= (WNDPROC
) NHCommandWndProc
;
539 wcex
.hInstance
= GetNHApp()->hApp
;
541 wcex
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
542 wcex
.hbrBackground
= mswin_get_brush(NHW_KEYPAD
, MSWIN_COLOR_BG
);
543 wcex
.lpszMenuName
= NULL
;
544 wcex
.lpszClassName
= szNHCmdWindowClass
;
546 if (!RegisterClass(&wcex
)) {
547 panic("cannot register Map window class");
550 /* create default command set */
551 nhcmdset_current
= nhcmdset_default
= nhcmdset_create();
553 #ifdef WIN_CE_SMARTPHONE
554 plt
= nhcmdlayout_create("General", NH_CMDPAD_ROWS
, NH_CMDPAD_COLS
);
555 nhcmdlayout_init(plt
, cells_layout_general
);
556 nhcmdset_add(nhcmdset_current
, plt
);
558 plt
= nhcmdlayout_create("Movement", NH_CMDPAD_ROWS
, NH_CMDPAD_COLS
);
559 nhcmdlayout_init(plt
, cells_layout_movement
);
560 nhcmdset_add(nhcmdset_current
, plt
);
562 plt
= nhcmdlayout_create("Attack", NH_CMDPAD_ROWS
, NH_CMDPAD_COLS
);
563 nhcmdlayout_init(plt
, cells_layout_attack
);
564 nhcmdset_add(nhcmdset_current
, plt
);
566 plt
= nhcmdlayout_create("Item Handling", NH_CMDPAD_ROWS
, NH_CMDPAD_COLS
);
567 nhcmdlayout_init(plt
, cells_layout_item_handling
);
568 nhcmdset_add(nhcmdset_current
, plt
);
570 plt
= nhcmdlayout_create("Game Controls", NH_CMDPAD_ROWS
, NH_CMDPAD_COLS
);
571 nhcmdlayout_init(plt
, cells_layout_game
);
572 nhcmdset_add(nhcmdset_current
, plt
);
574 plt
= nhcmdlayout_create("Advanced Movement", NH_CMDPAD_ROWS
,
576 nhcmdlayout_init(plt
, cells_layout_adv_movement
);
577 nhcmdset_add(nhcmdset_current
, plt
);
579 plt
= nhcmdlayout_create("Item Lookup", NH_CMDPAD_ROWS
, NH_CMDPAD_COLS
);
580 nhcmdlayout_init(plt
, cells_layout_lookup
);
581 nhcmdset_add(nhcmdset_current
, plt
);
585 nhcmdlayout_create("Wizard Mode", NH_CMDPAD_ROWS
, NH_CMDPAD_COLS
);
586 nhcmdlayout_init(plt
, cells_layout_wizard
);
587 nhcmdset_add(nhcmdset_current
, plt
);
590 #else /* ! WIN_CE_SMARTPHONE */
591 plt
= nhcmdlayout_create("lowercase", NH_CMDPAD_ROWS
, NH_CMDPAD_COLS
);
592 nhcmdlayout_init(plt
, cells_layout_mod1
);
593 nhcmdset_add(nhcmdset_current
, plt
);
595 plt
= nhcmdlayout_create("uppercase", NH_CMDPAD_ROWS
, NH_CMDPAD_COLS
);
596 nhcmdlayout_init(plt
, cells_layout_mod2
);
597 nhcmdset_add(nhcmdset_current
, plt
);
598 #endif /* WIN_CE_SMARTPHONE */
600 /*-------------------------------------------------------------------------*/
602 NHCommandWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
609 onCreate(hWnd
, wParam
, lParam
);
617 LayoutCmdWindow(hWnd
);
621 onMouseDown(hWnd
, wParam
, lParam
);
625 /* proceed only if if have mouse focus (set in onMouseDown() -
626 left mouse button is pressed) */
627 if (GetCapture() == hWnd
) {
628 onMouseMove(hWnd
, wParam
, lParam
);
636 /* proceed only if if have mouse focus (set in onMouseDown()) */
637 if (GetCapture() == hWnd
) {
638 onMouseUp(hWnd
, wParam
, lParam
);
646 data
= (PNHCmdWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
647 for (i
= 0; i
<= NH_CMDPAD_FONT_MAX
; i
++)
649 DeleteObject(data
->font
[i
]);
651 SetWindowLong(hWnd
, GWL_USERDATA
, (LONG
) 0);
655 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
659 /*-------------------------------------------------------------------------*/
672 /* get window data */
673 data
= (PNHCmdWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
675 hDC
= BeginPaint(hWnd
, &ps
);
677 if (!IsRectEmpty(&ps
.rcPaint
)) {
680 COLORREF OldBg
, OldFg
;
684 saveFont
= SelectObject(hDC
, data
->font
[NH_CMDPAD_FONT_NORMAL
]);
685 OldBg
= SetBkColor(hDC
, mswin_get_color(NHW_KEYPAD
, MSWIN_COLOR_BG
));
687 SetTextColor(hDC
, mswin_get_color(NHW_KEYPAD
, MSWIN_COLOR_FG
));
689 GetObject(data
->images
, sizeof(BITMAP
), (LPVOID
) &bm
);
691 hbrPattern
= CreatePatternBrush(data
->images
);
692 hPen
= CreatePen(PS_SOLID
, 1,
693 mswin_get_color(NHW_KEYPAD
, MSWIN_COLOR_FG
));
695 for (x
= 0, cell_index
= 0;
696 x
< nhcmdlayout_rows(data
->layout_current
); x
++)
697 for (y
= 0; y
< nhcmdlayout_columns(data
->layout_current
);
701 PNHCmdPadCell p_cell_data
;
704 nhcmdlayout_cell_direct(data
->layout_current
, cell_index
);
706 /* calculate the cell rectangle */
707 cell_rt
.left
= data
->cells
[cell_index
].orig
.x
;
708 cell_rt
.top
= data
->cells
[cell_index
].orig
.y
;
709 cell_rt
.right
= data
->cells
[cell_index
].orig
.x
710 + data
->cell_size
.cx
* p_cell_data
->mult
;
712 data
->cells
[cell_index
].orig
.y
+ data
->cell_size
.cy
;
715 hOldPen
= SelectObject(hDC
, hPen
);
716 pt
[0].x
= cell_rt
.left
;
717 pt
[0].y
= cell_rt
.top
;
718 pt
[1].x
= cell_rt
.right
;
719 pt
[1].y
= cell_rt
.top
;
720 pt
[2].x
= cell_rt
.right
;
721 pt
[2].y
= cell_rt
.bottom
;
722 pt
[3].x
= cell_rt
.left
;
723 pt
[3].y
= cell_rt
.bottom
;
724 pt
[4].x
= cell_rt
.left
;
725 pt
[4].y
= cell_rt
.top
;
726 Polyline(hDC
, pt
, 5);
727 SelectObject(hDC
, hOldPen
);
729 /* calculate clipping rectangle for the text */
735 /* draw the cell text */
736 if (p_cell_data
->image
<= 0) {
737 SelectObject(hDC
, data
->font
[-p_cell_data
->image
]);
738 DrawText(hDC
, NH_A2W(p_cell_data
->text
, wbuf
, BUFSZ
),
739 strlen(p_cell_data
->text
), &cell_rt
,
740 DT_CENTER
| DT_VCENTER
| DT_SINGLELINE
747 bmOffset
= (p_cell_data
->image
- 1) * bm
.bmHeight
;
750 ((cell_rt
.left
+ cell_rt
.right
)
751 - min(bm
.bmHeight
, (cell_rt
.right
- cell_rt
.left
)))
754 ((cell_rt
.bottom
+ cell_rt
.top
)
755 - min(bm
.bmHeight
, (cell_rt
.bottom
- cell_rt
.top
)))
759 + min(bm
.bmHeight
, (cell_rt
.right
- cell_rt
.left
));
762 + min(bm
.bmHeight
, (cell_rt
.bottom
- cell_rt
.top
));
764 SetBrushOrgEx(hDC
, bitmap_rt
.left
- bmOffset
,
765 bitmap_rt
.top
, NULL
);
766 oldBr
= SelectObject(hDC
, hbrPattern
);
767 PatBlt(hDC
, bitmap_rt
.left
, bitmap_rt
.top
,
768 bitmap_rt
.right
- bitmap_rt
.left
,
769 bitmap_rt
.bottom
- bitmap_rt
.top
, PATCOPY
);
770 SelectObject(hDC
, oldBr
);
773 /* invert the cell if it is selected */
774 if (data
->cells
[cell_index
].state
== NH_CST_CHECKED
) {
775 IntersectRect(&cell_rt
, &cell_rt
, &ps
.rcPaint
);
776 PatBlt(hDC
, cell_rt
.left
, cell_rt
.top
,
777 cell_rt
.right
- cell_rt
.left
,
778 cell_rt
.bottom
- cell_rt
.top
, DSTINVERT
);
782 SetTextColor(hDC
, OldFg
);
783 SetBkColor(hDC
, OldBg
);
784 SelectObject(hDC
, saveFont
);
785 DeleteObject(hbrPattern
);
790 /*-------------------------------------------------------------------------*/
792 onCreate(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
796 /* set window data */
797 data
= (PNHCmdWindow
) malloc(sizeof(NHCmdWindow
));
799 panic("out of memory");
801 ZeroMemory(data
, sizeof(NHCmdWindow
));
802 SetWindowLong(hWnd
, GWL_USERDATA
, (LONG
) data
);
804 data
->active_cell
= -1;
806 /* load images bitmap */
807 data
->images
= LoadBitmap(GetNHApp()->hApp
, MAKEINTRESOURCE(IDB_KEYPAD
));
809 panic("cannot load keypad bitmap");
811 /* create default layouts */
812 data
->layout_current
= 0;
813 data
->layout_save
= 0;
816 #if defined(WIN_CE_SMARTPHONE)
817 data
->layout_selected
= nhcmdset_get(nhcmdset_current
, 0);
820 /* set default layout */
821 SetCmdWindowLayout(hWnd
, nhcmdset_get(nhcmdset_current
, 0));
823 /*-------------------------------------------------------------------------*/
825 LayoutCmdWindow(HWND hWnd
)
835 GetClientRect(hWnd
, &clrt
);
836 if (IsRectEmpty(&clrt
))
839 data
= (PNHCmdWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
840 if (!data
->layout_current
)
843 /* calculate cell size */
844 windowSize
.cx
= clrt
.right
- clrt
.left
;
845 windowSize
.cy
= clrt
.bottom
- clrt
.top
;
846 CalculateCellSize(hWnd
, &data
->cell_size
, &windowSize
);
848 /* initialize display cells aray */
851 for (i
= 0, index
= 0; i
< nhcmdlayout_rows(data
->layout_current
); i
++) {
852 for (j
= 0; j
< nhcmdlayout_columns(data
->layout_current
);
854 data
->cells
[index
].orig
.x
= x
;
855 data
->cells
[index
].orig
.y
= y
;
856 data
->cells
[index
].type
=
857 nhcmdlayout_cell_direct(data
->layout_current
, index
)->type
;
859 switch (data
->cells
[index
].type
) {
861 data
->cells
[index
].state
= data
->is_ctrl
? NH_CST_CHECKED
: 0;
864 data
->cells
[index
].state
= data
->is_caps
? NH_CST_CHECKED
: 0;
867 data
->cells
[index
].state
=
868 data
->is_shift
? NH_CST_CHECKED
: 0;
871 data
->cells
[index
].state
= 0;
874 x
+= data
->cell_size
.cx
875 * nhcmdlayout_cell_direct(data
->layout_current
, index
)->mult
;
878 y
+= data
->cell_size
.cy
;
881 /* create font for display cell text */
882 for (i
= 0; i
<= NH_CMDPAD_FONT_MAX
; i
++)
884 DeleteObject(data
->font
[i
]);
886 ZeroMemory(&lgfnt
, sizeof(lgfnt
));
887 lgfnt
.lfHeight
= data
->cell_size
.cy
; // height of font
888 lgfnt
.lfWidth
= 0; // average character width
889 lgfnt
.lfEscapement
= 0; // angle of escapement
890 lgfnt
.lfOrientation
= 0; // base-line orientation angle
891 lgfnt
.lfWeight
= FW_NORMAL
; // font weight
892 lgfnt
.lfItalic
= FALSE
; // italic attribute option
893 lgfnt
.lfUnderline
= FALSE
; // underline attribute option
894 lgfnt
.lfStrikeOut
= FALSE
; // strikeout attribute option
895 lgfnt
.lfCharSet
= ANSI_CHARSET
; // character set identifier
896 lgfnt
.lfOutPrecision
= OUT_DEFAULT_PRECIS
; // output precision
897 lgfnt
.lfClipPrecision
= CLIP_CHARACTER_PRECIS
; // clipping precision
898 lgfnt
.lfQuality
= DEFAULT_QUALITY
; // output quality
899 if (iflags
.wc_font_message
&& *iflags
.wc_font_message
) {
900 lgfnt
.lfPitchAndFamily
= DEFAULT_PITCH
; // pitch and family
901 NH_A2W(iflags
.wc_font_message
, lgfnt
.lfFaceName
, LF_FACESIZE
);
903 lgfnt
.lfPitchAndFamily
= VARIABLE_PITCH
; // pitch and family
905 data
->font
[NH_CMDPAD_FONT_NORMAL
] = CreateFontIndirect(&lgfnt
);
907 InvalidateRect(hWnd
, NULL
, TRUE
);
909 /*-------------------------------------------------------------------------*/
911 SetCmdWindowLayout(HWND hWnd
, PNHCmdLayout layout
)
916 data
= (PNHCmdWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
917 if (data
->layout_current
== layout
)
920 data
->layout_current
= layout
;
921 size
= sizeof(NHCmdPadLayoutCell
) * nhcmdlayout_rows(layout
)
922 * nhcmdlayout_columns(layout
);
923 data
->cells
= (PNHCmdPadLayoutCell
) realloc(data
->cells
, size
);
924 ZeroMemory(data
->cells
, size
);
925 LayoutCmdWindow(hWnd
);
927 /*-------------------------------------------------------------------------*/
929 onMouseDown(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
934 /* get mouse coordinates */
935 mpt
.x
= LOWORD(lParam
);
936 mpt
.y
= HIWORD(lParam
);
938 /* map mouse coordinates to the display cell */
939 data
= (PNHCmdWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
940 data
->active_cell
= CellFromPoint(data
, mpt
);
941 if (data
->active_cell
== -1)
944 /* set mouse focus to the current window */
947 /* invert the selection */
948 HighlightCell(hWnd
, data
->active_cell
,
949 (data
->cells
[data
->active_cell
].state
!= NH_CST_CHECKED
));
951 /*-------------------------------------------------------------------------*/
953 onMouseMove(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
959 /* get mouse coordinates */
960 mpt
.x
= LOWORD(lParam
);
961 mpt
.y
= HIWORD(lParam
);
963 /* map mouse coordinates to the display cell */
964 data
= (PNHCmdWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
965 newActiveCell
= CellFromPoint(data
, mpt
);
966 if (data
->active_cell
== -1)
969 /* if mouse is within orginal display cell - select the cell otherwise
970 clear the selection */
971 switch (nhcmdlayout_cell_direct(data
->layout_current
, data
->active_cell
)
974 HighlightCell(hWnd
, data
->active_cell
,
975 (newActiveCell
== data
->active_cell
));
979 HighlightCell(hWnd
, data
->active_cell
,
980 ((newActiveCell
== data
->active_cell
) ? !data
->is_ctrl
985 HighlightCell(hWnd
, data
->active_cell
,
986 ((newActiveCell
== data
->active_cell
) ? !data
->is_caps
991 /*-------------------------------------------------------------------------*/
993 onMouseUp(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
997 /* release mouse capture */
1000 /* get active display cell */
1001 data
= (PNHCmdWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
1002 if (data
->active_cell
== -1)
1005 ActivateCell(hWnd
, data
->active_cell
);
1007 data
->active_cell
= -1;
1009 /*-------------------------------------------------------------------------*/
1011 ActivateCell(HWND hWnd
, int cell
)
1014 PNHCmdPadCell p_cell_data
;
1017 data
= (PNHCmdWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
1020 p_cell_data
= nhcmdlayout_cell_direct(data
->layout_current
, cell
);
1022 /* act depending on the cell type:
1023 CAPS - change layout
1024 CTRL - modify CTRL status
1025 REG - place keyboard event on the anethack input queue
1027 switch (p_cell_data
->type
) {
1029 if (data
->is_ctrl
) {
1030 PushNethackCommand(p_cell_data
->f_char
, 1);
1033 for (i
= 0; i
< nhcmdlayout_rows(data
->layout_current
)
1034 * nhcmdlayout_columns(data
->layout_current
);
1036 if (nhcmdlayout_cell_direct(data
->layout_current
, i
)->type
1038 HighlightCell(hWnd
, i
, data
->is_ctrl
);
1042 PushNethackCommand(p_cell_data
->f_char
, 0);
1044 HighlightCell(hWnd
, cell
, FALSE
);
1046 // select a new layout if present
1047 i
= (int) p_cell_data
->data
;
1049 if (data
->layout_save
)
1050 SetCmdWindowLayout(hWnd
, data
->layout_save
);
1051 data
->layout_save
= NULL
;
1053 if (!data
->layout_save
)
1054 data
->layout_save
= data
->layout_current
;
1055 SetCmdWindowLayout(hWnd
, nhcmdset_get(nhcmdset_current
, i
));
1058 if (!data
->is_shift
)
1060 // else fall through and reset the shift
1063 data
->is_shift
= !data
->is_shift
;
1064 SetCmdWindowLayout(hWnd
, (data
->is_shift
^ data
->is_caps
)
1065 ? nhcmdset_get(nhcmdset_current
, 1)
1066 : nhcmdset_get(nhcmdset_current
, 0));
1067 data
->cells
[cell
].state
= data
->is_shift
? NH_CST_CHECKED
: 0;
1068 InvalidateRect(hWnd
, NULL
, TRUE
);
1072 data
->is_ctrl
= !data
->is_ctrl
;
1073 HighlightCell(hWnd
, cell
, data
->is_ctrl
);
1077 data
->is_caps
= !data
->is_caps
;
1078 SetCmdWindowLayout(hWnd
, (data
->is_shift
^ data
->is_caps
)
1079 ? nhcmdset_get(nhcmdset_current
, 1)
1080 : nhcmdset_get(nhcmdset_current
, 0));
1081 data
->cells
[cell
].state
= data
->is_caps
? NH_CST_CHECKED
: 0;
1082 InvalidateRect(hWnd
, NULL
, TRUE
);
1085 case NH_CELL_LAYOUT_NEW
: {
1086 PNHCmdLayout pLayout
;
1088 HighlightCell(hWnd
, cell
, FALSE
);
1090 pLayout
= (PNHCmdLayout
) p_cell_data
->data
;
1092 SetCmdWindowLayout(hWnd
, pLayout
);
1096 case NH_CELL_LAYOUT_MENU
: {
1100 menu_item
*selected
= 0;
1103 HighlightCell(hWnd
, cell
, FALSE
);
1105 pSet
= (PNHCmdSet
) p_cell_data
->data
;
1107 pSet
= nhcmdset_default
;
1109 wid
= mswin_create_nhwindow(NHW_MENU
);
1110 mswin_start_menu(wid
);
1111 for (i
= 0; i
< nhcmdset_count(pSet
); i
++) {
1112 any
.a_void
= nhcmdset_get(pSet
, i
);
1113 mswin_add_menu(wid
, NO_GLYPH
, &any
, 'a' + i
, 0, ATR_NONE
,
1114 nhcmdset_get_name(pSet
, i
), FALSE
);
1116 mswin_end_menu(wid
, "Select keypad layout");
1117 i
= select_menu(wid
, PICK_ONE
, &selected
);
1118 mswin_destroy_nhwindow(wid
);
1121 #if defined(WIN_CE_SMARTPHONE)
1122 data
->layout_selected
= (PNHCmdLayout
) selected
[0].item
.a_void
;
1124 SetCmdWindowLayout(hWnd
, (PNHCmdLayout
) selected
[0].item
.a_void
);
1129 /*-------------------------------------------------------------------------*/
1131 CellFromPoint(PNHCmdWindow data
, POINT pt
)
1134 for (i
= 0; i
< nhcmdlayout_rows(data
->layout_current
)
1135 * nhcmdlayout_columns(data
->layout_current
);
1138 cell_rt
.left
= data
->cells
[i
].orig
.x
;
1139 cell_rt
.top
= data
->cells
[i
].orig
.y
;
1141 data
->cells
[i
].orig
.x
1142 + data
->cell_size
.cx
1143 * nhcmdlayout_cell_direct(data
->layout_current
, i
)->mult
;
1144 cell_rt
.bottom
= data
->cells
[i
].orig
.y
+ data
->cell_size
.cy
;
1145 if (PtInRect(&cell_rt
, pt
))
1150 /*-------------------------------------------------------------------------*/
1152 CalculateCellSize(HWND hWnd
, LPSIZE pSize
, LPSIZE pWindowSize
)
1156 data
= (PNHCmdWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
1162 /* if windows size is specified - attempt ro stretch cells across
1163 the the window size. If not - make default cell size based on
1164 10 points font. Make sure that cell cesize does not exceeds 20 points
1166 if (pWindowSize
->cx
> 0)
1168 pWindowSize
->cx
/ nhcmdlayout_columns(data
->layout_current
);
1170 pSize
->cx
= 10 * GetDeviceCaps(hdc
, LOGPIXELSX
) / 72;
1171 pSize
->cx
= min(pSize
->cx
, 20 * GetDeviceCaps(hdc
, LOGPIXELSX
) / 72);
1173 if (pWindowSize
->cy
> 0)
1174 pSize
->cy
= pWindowSize
->cy
/ nhcmdlayout_rows(data
->layout_current
);
1176 pSize
->cy
= 10 * GetDeviceCaps(hdc
, LOGPIXELSY
) / 72;
1177 pSize
->cy
= min(pSize
->cy
, 20 * GetDeviceCaps(hdc
, LOGPIXELSY
) / 72);
1179 ReleaseDC(hWnd
, hdc
);
1181 /*-------------------------------------------------------------------------*/
1183 HighlightCell(HWND hWnd
, int cell
, BOOL isSelected
)
1189 data
= (PNHCmdWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
1190 prevState
= data
->cells
[cell
].state
;
1191 data
->cells
[cell
].state
= (isSelected
) ? NH_CST_CHECKED
: 0;
1193 if (prevState
!= data
->cells
[cell
].state
) {
1195 PatBlt(hDC
, data
->cells
[cell
].orig
.x
+ 1,
1196 data
->cells
[cell
].orig
.y
+ 1,
1198 * nhcmdlayout_cell_direct(data
->layout_current
, cell
)
1201 data
->cell_size
.cy
- 2, DSTINVERT
);
1202 ReleaseDC(hWnd
, hDC
);
1205 /*-------------------------------------------------------------------------*/
1207 PushNethackCommand(const char *cmd_char_str
, int is_ctrl
)
1209 while (*cmd_char_str
) {
1211 NHEVENT_KBD(C(*cmd_char_str
));
1213 NHEVENT_KBD(*cmd_char_str
);
1219 /*-------------------------------------------------------------------------*/
1220 /*------------------- keyboard keys layout functions ----------------------*/
1221 /*-------------------------------------------------------------------------*/
1223 nhcmdlayout_create(const char *name
, int rows
, int columns
)
1228 i
= sizeof(NHCmdLayout
) + rows
* columns
* sizeof(NHCmdPadCell
);
1229 p
= (PNHCmdLayout
) malloc(i
);
1232 p
->columns
= columns
;
1233 strncpy(p
->name
, name
, sizeof(p
->name
) - 1);
1234 for (i
= 0; i
< rows
* columns
; i
++) {
1235 p
->cells
[i
].cmd_code
= -1;
1236 p
->cells
[i
].image
= -NH_CMDPAD_FONT_NORMAL
;
1237 p
->cells
[i
].type
= 1;
1238 p
->cells
[i
].mult
= 1;
1242 /*-------------------------------------------------------------------------*/
1244 nhcmdlayout_init(PNHCmdLayout p
, PNHCmdPadCell cells
)
1246 memcpy(p
->cells
, cells
, p
->rows
* p
->columns
* sizeof(NHCmdPadCell
));
1250 nhcmdlayout_destroy(PNHCmdLayout p
)
1255 /*-------------------------------------------------------------------------*/
1256 /*----------------- keyboard keys layout set functions --------------------*/
1257 /*-------------------------------------------------------------------------*/
1262 p
= (PNHCmdSet
) malloc(sizeof(NHCmdSet
));
1263 ZeroMemory(p
, sizeof(NHCmdSet
));
1266 /*-------------------------------------------------------------------------*/
1268 nhcmdset_count(PNHCmdSet p
)
1273 /*-------------------------------------------------------------------------*/
1275 nhcmdset_get(PNHCmdSet p
, int index
)
1278 assert(index
>= 0 && index
< p
->count
);
1279 return p
->elements
[index
].layout
;
1281 /*-------------------------------------------------------------------------*/
1283 nhcmdset_get_name(PNHCmdSet p
, int index
)
1286 assert(index
>= 0 && index
< p
->count
);
1287 return p
->elements
[index
].layout
->name
;
1289 /*-------------------------------------------------------------------------*/
1291 nhcmdset_add(PNHCmdSet p
, PNHCmdLayout layout
)
1294 assert(p
->count
< NH_CMDSET_MAXSIZE
);
1295 p
->elements
[p
->count
].layout
= layout
;
1296 p
->elements
[p
->count
].free_on_destroy
= 0;
1299 /*-------------------------------------------------------------------------*/
1301 nhcmdset_destroy(PNHCmdSet p
)
1305 for (i
= 0; i
< p
->count
; i
++) {
1306 if (p
->elements
[i
].free_on_destroy
) {
1307 nhcmdlayout_destroy(p
->elements
[i
].layout
);
1312 /*-------------------------------------------------------------------------*/
1314 #if defined(WIN_CE_SMARTPHONE)
1315 /* special keypad input handling for SmartPhone
1316 the phone keypad maps to VK_* as shown below.
1317 some keys might not be present, e.g. VK_TFLIP
1318 sofkey1 softkey2 VK_TSOFT1, VK_TSOFT2
1320 < + > VK_TLEFT, VK_TACTION, VK_TRIGHT
1322 home back VK_THOME, VK_TBACK
1323 talk end VK_TTALK, VK_TEND
1327 * 0 # VK_TSTAR, VK_TPOUND
1328 other buttons include
1330 VK_TPOWER, VK_TVOLUMEUP, VK_TVOLUMEDOWN
1334 NHSPhoneTranslateKbdMessage(WPARAM wParam
, LPARAM lParam
, BOOL keyDown
)
1339 /* get window data */
1340 data
= (PNHCmdWindow
) GetWindowLong(GetNHApp()->hCmdWnd
, GWL_USERDATA
);
1395 HighlightCell(GetNHApp()->hCmdWnd
, index
, keyDown
);
1397 ActivateCell(GetNHApp()->hCmdWnd
, index
);
1403 /*-------------------------------------------------------------------------*/
1405 NHSPhoneSetKeypadFromString(const char *str
)
1409 PNHCmdLayout layout_prev
= 0;
1410 PNHCmdLayout layout_cur
= 0;
1415 assert(NH_CMDPAD_ROWS
== 4);
1417 data
= (PNHCmdWindow
) GetWindowLong(GetNHApp()->hCmdWnd
, GWL_USERDATA
);
1421 p
= nhcmdset_create();
1423 ZeroMemory(buf
, sizeof(buf
));
1424 if (sscanf(str
, "%s or %s", buf
[1], buf
[0]) != 2) {
1425 ZeroMemory(buf
, sizeof(buf
));
1426 strncpy(buf
[0], str
, sizeof(buf
[0]) - 1);
1429 lcount
= 10; /* create new layout on the first iteration */
1430 for (i
= 0; i
< 2; i
++) {
1433 char c_start
, c_end
, c_char
;
1435 /* parse character ranges */
1436 if (isalnum((c_start
= s
[0])) && s
[1] == '-'
1437 && isalnum((c_end
= s
[2]))) {
1440 c_start
= c_end
= *s
;
1443 for (c_char
= c_start
; c_char
<= c_end
; c_char
++) {
1447 layout_prev
= layout_cur
;
1448 layout_cur
= nhcmdlayout_create("noname", NH_CMDPAD_ROWS
,
1450 nhcmdlayout_init(layout_cur
, cells_layout_menu
);
1452 nhcmdlayout_cell(layout_cur
, 3, 0)->data
= layout_prev
;
1453 nhcmdlayout_cell(layout_cur
, 3, 2)->data
= 0;
1455 nhcmdset_add(p
, layout_cur
);
1456 p
->elements
[p
->count
- 1].free_on_destroy
= 1;
1459 nhcmdlayout_cell(layout_prev
, 3, 2)->data
=
1465 lcount
= 10; // skip '#'
1466 nhcmdlayout_cell_direct(layout_cur
, lcount
)->f_char
[0] =
1468 if (c_char
== '\033') {
1469 strcpy(nhcmdlayout_cell_direct(layout_cur
, lcount
)->text
,
1471 nhcmdlayout_cell_direct(layout_cur
, lcount
)->image
=
1472 14; /* 14 is a ESC symbol in IDB_KEYPAD */
1474 nhcmdlayout_cell_direct(layout_cur
, lcount
)->text
[0] =
1476 nhcmdlayout_cell_direct(layout_cur
, lcount
)->text
[1] =
1480 /* increment character count in the current layout */
1484 /* prepareg next charcter from the source string */
1489 /* install the new set */
1490 if (nhcmdset_current
!= nhcmdset_default
)
1491 nhcmdset_destroy(nhcmdset_current
);
1492 nhcmdset_current
= p
;
1493 SetCmdWindowLayout(GetNHApp()->hCmdWnd
,
1494 nhcmdset_get(nhcmdset_current
, 0));
1496 /*-------------------------------------------------------------------------*/
1498 NHSPhoneSetKeypadDirection()
1502 data
= (PNHCmdWindow
) GetWindowLong(GetNHApp()->hCmdWnd
, GWL_USERDATA
);
1506 if (nhcmdset_current
!= nhcmdset_default
)
1507 nhcmdset_destroy(nhcmdset_current
);
1508 nhcmdset_current
= nhcmdset_default
;
1509 SetCmdWindowLayout(GetNHApp()->hCmdWnd
,
1510 nhcmdset_get(nhcmdset_current
, NH_LAYOUT_MOVEMENT
));
1512 /*-------------------------------------------------------------------------*/
1514 NHSPhoneSetKeypadDefault()
1518 data
= (PNHCmdWindow
) GetWindowLong(GetNHApp()->hCmdWnd
, GWL_USERDATA
);
1522 if (nhcmdset_current
!= nhcmdset_default
)
1523 nhcmdset_destroy(nhcmdset_current
);
1524 nhcmdset_current
= nhcmdset_default
;
1525 SetCmdWindowLayout(GetNHApp()->hCmdWnd
,
1526 data
->layout_selected
1527 ? data
->layout_selected
1528 : nhcmdset_get(nhcmdset_current
, 0));
1531 #endif /* defined (WIN_CE_SMARTHPONE) */