1532 lines
56 KiB
C
1532 lines
56 KiB
C
/* NetHack 3.6 mhcmd.c $NHDT-Date: 1432512800 2015/05/25 00:13:20 $ $NHDT-Branch: master $:$NHDT-Revision: 1.14 $ */
|
|
/* NetHack may be freely redistributed. See license for details. */
|
|
|
|
#include "winMS.h"
|
|
#include <assert.h>
|
|
#include "mhcmd.h"
|
|
#include "mhinput.h"
|
|
#include "mhcolor.h"
|
|
|
|
static TCHAR szNHCmdWindowClass[] = TEXT("MSNethackCmdWndClass");
|
|
|
|
#ifndef C
|
|
#define C(c) (0x1f & (c))
|
|
#endif
|
|
|
|
/* cell status 0 */
|
|
#define NH_CST_CHECKED 1
|
|
|
|
/* fonts */
|
|
#define NH_CMDPAD_FONT_NORMAL 0
|
|
#define NH_CMDPAD_FONT_MAX 0
|
|
|
|
/* type of the cell */
|
|
#define NH_CELL_REG 0
|
|
#define NH_CELL_CTRL 1
|
|
#define NH_CELL_CAP 2
|
|
#define NH_CELL_SHIFT 3
|
|
#define NH_CELL_LAYOUT_NEW 4
|
|
#define NH_CELL_LAYOUT_MENU 5
|
|
|
|
#define NH_CMDSET_MAXSIZE 64
|
|
|
|
/* Keypad cell information
|
|
|
|
NHCmdPadCell.cell_type NHCmdPadCell.data
|
|
----------- ----------
|
|
NH_CELL_REG (int)>=0 - index in the
|
|
current keypad layout set (loads a new layout)
|
|
-1 - restore default (saved) layout
|
|
NH_CELL_CTRL not used
|
|
NH_CELL_CAP not used
|
|
NH_CELL_SHIFT not used
|
|
NH_CELL_LAYOUT_NEW pointer to the new keypad layout
|
|
layout (NHCmdLayout*)
|
|
NH_CELL_LAYOUT_MENU pointer to the layout set (NHCmdSet* - if
|
|
NULL then nhcmdset_default is used)
|
|
*/
|
|
typedef struct t_NHCmdPadCell {
|
|
UINT cmd_code; /* Windows command code (menu processing - not implemented
|
|
- set to -1) */
|
|
char f_char[16]; /* nethack char */
|
|
char text[16]; /* display text */
|
|
int image; /* >0 - image ID in IDB_KEYPAD bitmap
|
|
<=0 - absolute index of the font table */
|
|
int type; /* cell type */
|
|
int mult; /* cell width multiplier */
|
|
void *data; /* internal data for the cell type */
|
|
} NHCmdPadCell, *PNHCmdPadCell;
|
|
|
|
/* command layout */
|
|
typedef struct t_NHCmdLayout {
|
|
char name[64];
|
|
int rows;
|
|
int columns;
|
|
NHCmdPadCell cells[];
|
|
} NHCmdLayout, *PNHCmdLayout;
|
|
|
|
/* set of command layouts */
|
|
typedef struct t_NHCmdSet {
|
|
int count;
|
|
struct t_NHCmdSetElem {
|
|
PNHCmdLayout layout;
|
|
BOOL free_on_destroy;
|
|
} elements[NH_CMDSET_MAXSIZE];
|
|
} NHCmdSet, *PNHCmdSet;
|
|
|
|
/* display cell layout */
|
|
typedef struct t_NHCmdPadLayoutCell {
|
|
POINT orig; /* origin of the cell rect */
|
|
BYTE type; /* cell type */
|
|
int state; /* cell state */
|
|
} NHCmdPadLayoutCell, *PNHCmdPadLayoutCell;
|
|
|
|
/* command window data */
|
|
typedef struct mswin_nethack_cmd_window {
|
|
SIZE cell_size; /* cell size */
|
|
HFONT font[NH_CMDPAD_FONT_MAX + 1]; /* fonts for cell text */
|
|
HBITMAP images; /* key images map */
|
|
int active_cell; /* current active cell */
|
|
|
|
boolean is_caps; /* is CAPS selected */
|
|
boolean is_ctrl; /* is CRTL selected */
|
|
boolean is_shift; /* is SHIFT selected */
|
|
|
|
PNHCmdLayout layout_current; /* current layout */
|
|
PNHCmdLayout layout_save; /* saved layout */
|
|
PNHCmdPadLayoutCell cells; /* display cells */
|
|
|
|
#if defined(WIN_CE_SMARTPHONE)
|
|
PNHCmdLayout layout_selected; /* since we use
|
|
layout
|
|
command for menu also
|
|
we need to store the layout
|
|
that was
|
|
selected by a user
|
|
*/
|
|
#endif
|
|
} NHCmdWindow, *PNHCmdWindow;
|
|
|
|
LRESULT CALLBACK NHCommandWndProc(HWND, UINT, WPARAM, LPARAM);
|
|
static void register_command_window_class();
|
|
static void LayoutCmdWindow(HWND hWnd);
|
|
static void SetCmdWindowLayout(HWND hWnd, PNHCmdLayout layout);
|
|
static int CellFromPoint(PNHCmdWindow data, POINT pt);
|
|
static void CalculateCellSize(HWND hWnd, LPSIZE pSize, LPSIZE windowSize);
|
|
static void HighlightCell(HWND hWnd, int cell, BOOL isSelected);
|
|
static void ActivateCell(HWND hWnd, int cell);
|
|
static void PushNethackCommand(const char *cmd_char_str, int is_ctrl);
|
|
|
|
/*------------------- keyboard keys layout functions -----------------------*/
|
|
PNHCmdLayout nhcmdlayout_create(const char *name, int rows, int columns);
|
|
void nhcmdlayout_init(PNHCmdLayout p, PNHCmdPadCell cells);
|
|
#define nhcmdlayout_rows(p) ((p)->rows)
|
|
#define nhcmdlayout_columns(p) ((p)->columns)
|
|
#define nhcmdlayout_row(p, x) (&((p)->cells[(p)->columns * (x)]))
|
|
#define nhcmdlayout_cell(p, x, y) (&((p)->cells[(p)->columns * (x) + (y)]))
|
|
#define nhcmdlayout_cell_direct(p, i) (&((p)->cells[(i)]))
|
|
void nhcmdlayout_destroy(PNHCmdLayout p);
|
|
|
|
/*----------------- keyboard keys layout set functions ---------------------*/
|
|
PNHCmdSet nhcmdset_create();
|
|
int nhcmdset_count(PNHCmdSet p);
|
|
PNHCmdLayout nhcmdset_get(PNHCmdSet p, int index);
|
|
const char *nhcmdset_get_name(PNHCmdSet p, int index);
|
|
void nhcmdset_add(PNHCmdSet p, PNHCmdLayout layout);
|
|
void nhcmdset_destroy(PNHCmdSet p);
|
|
|
|
/*-------------------- message handlers -----------------------------------*/
|
|
static void onPaint(HWND hWnd); // on WM_PAINT
|
|
static void onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam); // on WM_CREATE
|
|
static void onMouseDown(HWND hWnd, WPARAM wParam,
|
|
LPARAM lParam); // on WM_LBUTTONDOWN
|
|
static void onMouseMove(HWND hWnd, WPARAM wParam,
|
|
LPARAM lParam); // on WM_MOUSEMOVE
|
|
static void onMouseUp(HWND hWnd, WPARAM wParam,
|
|
LPARAM lParam); // on WM_LBUTTONUP
|
|
|
|
/*----------------------- static data -------------------------------------*/
|
|
static PNHCmdSet nhcmdset_current = 0;
|
|
static PNHCmdSet nhcmdset_default = 0;
|
|
|
|
/*---------------------- Pre-definde keyboard layouts --------------------*/
|
|
#ifdef WIN_CE_SMARTPHONE
|
|
|
|
/* dimensions of the command pad */
|
|
#define NH_CMDPAD_ROWS 4
|
|
#define NH_CMDPAD_COLS 3
|
|
#define NH_CMDPAD_CELLNUM (NH_CMDPAD_COLS * NH_CMDPAD_ROWS)
|
|
|
|
/* layout indexes */
|
|
#define NH_LAYOUT_GENERAL 0
|
|
#define NH_LAYOUT_MOVEMENT 1
|
|
#define NH_LAYOUT_ATTACK 2
|
|
#define NH_LAYOUT_ITEM_HANDLING 3
|
|
#define NH_LAYOUT_CONTROLS 4
|
|
#define NH_LAYOUT_ADV_MOVEMENT 5
|
|
#define NH_LAYOUT_ITEM_LOOKUP 6
|
|
#define NH_LAYOUT_WIZARD 7
|
|
|
|
/* template menu layout */
|
|
NHCmdPadCell cells_layout_menu[NH_CMDPAD_CELLNUM] = {
|
|
{ -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "", "<<", -NH_CMDPAD_FONT_NORMAL, NH_CELL_LAYOUT_NEW, 1, NULL },
|
|
{ -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "", ">>", -NH_CMDPAD_FONT_NORMAL, NH_CELL_LAYOUT_NEW, 1, NULL }
|
|
};
|
|
|
|
/* movement layout */
|
|
NHCmdPadCell cells_layout_movement[NH_CMDPAD_CELLNUM] = {
|
|
{ -1, "7", "7", 1, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "8", "8", 2, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "9", "9", 3, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "4", "4", 4, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, ".", ".", 5, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "6", "6", 6, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "1", "1", 7, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "2", "2", 8, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "3", "3", 9, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "<", "<", 10, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, ">", ">", 12, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
|
|
};
|
|
|
|
/* attack layout */
|
|
NHCmdPadCell cells_layout_attack[NH_CMDPAD_CELLNUM] = {
|
|
{ -1, "t", "t", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "w", "w", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "x", "x", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "f", "f", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "z", "z", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "Z", "Z", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "r", "r", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "a", "a", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "q", "q", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "\x04", "^D", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) - 1 },
|
|
{ -1, "F", "F", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) NH_LAYOUT_MOVEMENT },
|
|
{ -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
|
|
};
|
|
|
|
/* item handling layout */
|
|
NHCmdPadCell cells_layout_item_handling[NH_CMDPAD_CELLNUM] = {
|
|
{ -1, "W", "W", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "P", "P", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "d", "d", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "T", "T", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "R", "R", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "D", "D", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "=", "=", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "i", "i", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "Q", "Q", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "A", "A", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "I", "I", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
|
|
};
|
|
|
|
/* General */
|
|
NHCmdPadCell cells_layout_general[NH_CMDPAD_CELLNUM] = {
|
|
{ -1, "q", "q", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "e", "e", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "l", "l", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "s", "s", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "E", "E", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "\x01", "^A", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) - 1 },
|
|
{ -1, "c", "c", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "o", "o", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "p", "p", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, ":", ":", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, ",", ",", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
|
|
};
|
|
|
|
/* game controls layout */
|
|
NHCmdPadCell cells_layout_game[NH_CMDPAD_CELLNUM] = {
|
|
{ -1, "S", "S", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "h", "h", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "C", "C", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "@", "@", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "\\", "\\", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "O", "O", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "&", "&", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "\x18", "^X", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) - 1 },
|
|
{ -1, "\x10", "^P", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) - 1 },
|
|
{ -1, "X", "X", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "#", "#", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
|
|
};
|
|
|
|
/* advanced movement layout */
|
|
NHCmdPadCell cells_layout_adv_movement[NH_CMDPAD_CELLNUM] = {
|
|
{ -1, "g", "g", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) NH_LAYOUT_MOVEMENT },
|
|
{ -1, "G", "G", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) NH_LAYOUT_MOVEMENT },
|
|
{ -1, "m", "m", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) NH_LAYOUT_MOVEMENT },
|
|
{ -1, "M", "M", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) NH_LAYOUT_MOVEMENT },
|
|
{ -1, "_", "_", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "\x14", "^T", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) - 1 },
|
|
{ -1, "j", "j", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "<", "<", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, ">", ">", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "^", "^", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
|
|
};
|
|
|
|
/* item lookup layout */
|
|
NHCmdPadCell cells_layout_lookup[NH_CMDPAD_CELLNUM] = {
|
|
{ -1, ";", ";", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "^", "^", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "]", "]", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, ")", ")", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "=", "=", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "*", "*", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "(", "(", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "\"", "\"", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "$", "$", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "+", "+", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
|
|
};
|
|
|
|
/* wizard mode layout */
|
|
NHCmdPadCell cells_layout_wizard[NH_CMDPAD_CELLNUM] = {
|
|
{ -1, "\x05", "^e", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) - 1 },
|
|
{ -1, "\x06", "^f", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) - 1 },
|
|
{ -1, "\x07", "^g", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) - 1 },
|
|
{ -1, "\x09", "^i", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) - 1 },
|
|
{ -1, "\x0f", "^o", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) - 1 },
|
|
{ -1, "\x16", "^v", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) - 1 },
|
|
{ -1, "\x17", "^w", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) - 1 },
|
|
{ -1, "\x14", "^T", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
|
|
(void *) - 1 },
|
|
{ -1, "#", "#", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
|
|
};
|
|
|
|
#else /* !WIN_CE_SMARTPHONE */
|
|
|
|
/* dimensions of the command pad */
|
|
#define NH_CMDPAD_ROWS 4
|
|
#define NH_CMDPAD_COLS 14
|
|
#define NH_CMDPAD_CELLNUM (NH_CMDPAD_COLS * NH_CMDPAD_ROWS)
|
|
|
|
/* lowercase layout */
|
|
NHCmdPadCell cells_layout_mod1[NH_CMDPAD_ROWS * NH_CMDPAD_COLS] = {
|
|
{ -1, "7", "7", 1, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "8", "8", 2, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "9", "9", 3, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "\x1b", "Esc", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 2, NULL },
|
|
{ -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
|
|
NULL }, /* complement for ESC */
|
|
{ -1, "?", "?", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "*", "*", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, ",", ",", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "/", "/", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, ":", ":", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, ";", ";", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "-", "-", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "#", "#", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "^", "^", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
|
|
{ -1, "4", "4", 4, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "5", "5", 5, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "6", "6", 6, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, " ", "CAP", -NH_CMDPAD_FONT_NORMAL, NH_CELL_CAP, 2, NULL },
|
|
{ -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
|
|
NULL }, /* complement for CAPS */
|
|
{ -1, "a", "a", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "b", "b", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "c", "c", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "d", "d", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "e", "e", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "f", "f", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "g", "g", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "h", "h", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "i", "i", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
|
|
{ -1, "1", "1", 7, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "2", "2", 8, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "3", "3", 9, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, " ", "Shft", -NH_CMDPAD_FONT_NORMAL, NH_CELL_SHIFT, 2, NULL },
|
|
{ -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
|
|
NULL }, /* complement for shift */
|
|
{ -1, "j", "j", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "k", "k", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "l", "l", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "m", "m", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "n", "n", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "o", "o", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "p", "p", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "q", "q", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "r", "r", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
|
|
{ -1, "<", "<", 10, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, ".", ".", 11, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, ">", ">", 12, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, " ", "Ctrl", -NH_CMDPAD_FONT_NORMAL, NH_CELL_CTRL, 2, NULL },
|
|
{ -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
|
|
NULL }, /* complement for CTRL */
|
|
{ -1, "s", "s", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "t", "t", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "u", "u", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "v", "v", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "w", "w", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "x", "x", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "y", "y", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "z", "z", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "\\", "\\", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 }
|
|
};
|
|
|
|
/* uppercase layout */
|
|
NHCmdPadCell cells_layout_mod2[-NH_CMDPAD_ROWS * -NH_CMDPAD_COLS] = {
|
|
{ -1, "7", "7", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "8", "8", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "9", "9", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "\x1b", "Esc", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 2, NULL },
|
|
{ -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
|
|
NULL }, /* complement for ESC */
|
|
{ -1, "?", "?", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "*", "*", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "[", "[", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "(", "(", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, ")", ")", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "+", "+", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "=", "=", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "\"", "\"", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "$", "$", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
|
|
{ -1, "4", "4", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "5", "5", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "6", "6", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, " ", "CAP", -NH_CMDPAD_FONT_NORMAL, NH_CELL_CAP, 2, NULL },
|
|
{ -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
|
|
NULL }, /* complement for CAPS */
|
|
{ -1, "A", "A", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "B", "B", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "C", "C", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "D", "D", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "E", "E", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "F", "F", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "G", "G", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "H", "H", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "I", "I", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
|
|
{ -1, "1", "1", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "2", "2", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "3", "3", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, " ", "Shft", -NH_CMDPAD_FONT_NORMAL, NH_CELL_SHIFT, 2, NULL },
|
|
{ -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
|
|
NULL }, /* complement for shift */
|
|
{ -1, "J", "J", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "K", "K", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "L", "L", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "M", "M", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "N", "N", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "O", "O", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "P", "P", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "Q", "Q", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "R", "R", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
|
|
{ -1, "<", "<", 10, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "0", "0", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, ">", ">", 12, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, " ", "Ctrl", -NH_CMDPAD_FONT_NORMAL, NH_CELL_CTRL, 2, NULL },
|
|
{ -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
|
|
NULL }, /* complement for CTRL */
|
|
{ -1, "S", "S", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "T", "T", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "U", "U", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "V", "V", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "W", "W", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "X", "X", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "Y", "Y", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "Z", "Z", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
|
|
{ -1, "@", "@", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 }
|
|
};
|
|
|
|
#endif /* !WIN_CE_SMARTPHONE */
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
HWND
|
|
mswin_init_command_window()
|
|
{
|
|
static int run_once = 0;
|
|
HWND ret;
|
|
|
|
/* register window class */
|
|
if (!run_once) {
|
|
register_command_window_class();
|
|
run_once = 1;
|
|
}
|
|
|
|
/* create window */
|
|
ret = CreateWindow(
|
|
szNHCmdWindowClass, /* registered class name */
|
|
NULL, /* window name */
|
|
WS_CHILD | WS_CLIPSIBLINGS, /* window style */
|
|
0, /* horizontal position of window - set it later */
|
|
0, /* vertical position of window - set it later */
|
|
0, /* window width - set it later */
|
|
0, /* window height - set it later*/
|
|
GetNHApp()->hMainWnd, /* handle to parent or owner window */
|
|
NULL, /* menu handle or child identifier */
|
|
GetNHApp()->hApp, /* handle to application instance */
|
|
NULL); /* window-creation data */
|
|
if (!ret) {
|
|
panic("Cannot create command window");
|
|
}
|
|
return ret;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
/* calculate mimimum window size */
|
|
void
|
|
mswin_command_window_size(HWND hwnd, LPSIZE sz)
|
|
{
|
|
SIZE cell_size;
|
|
PNHCmdWindow data;
|
|
data = (PNHCmdWindow) GetWindowLong(hwnd, GWL_USERDATA);
|
|
if (!data) {
|
|
sz->cx = sz->cy = 0;
|
|
} else {
|
|
CalculateCellSize(hwnd, &cell_size, sz);
|
|
sz->cx = max(cell_size.cx * nhcmdlayout_columns(data->layout_current)
|
|
+ 2 * GetSystemMetrics(SM_CXBORDER),
|
|
sz->cx);
|
|
sz->cy = max(cell_size.cy * nhcmdlayout_rows(data->layout_current)
|
|
+ 2 * GetSystemMetrics(SM_CYBORDER),
|
|
sz->cy);
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
register_command_window_class()
|
|
{
|
|
WNDCLASS wcex;
|
|
PNHCmdLayout plt;
|
|
ZeroMemory(&wcex, sizeof(wcex));
|
|
|
|
/* window class */
|
|
wcex.style = CS_NOCLOSE;
|
|
wcex.lpfnWndProc = (WNDPROC) NHCommandWndProc;
|
|
wcex.cbClsExtra = 0;
|
|
wcex.cbWndExtra = 0;
|
|
wcex.hInstance = GetNHApp()->hApp;
|
|
wcex.hIcon = NULL;
|
|
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wcex.hbrBackground = mswin_get_brush(NHW_KEYPAD, MSWIN_COLOR_BG);
|
|
wcex.lpszMenuName = NULL;
|
|
wcex.lpszClassName = szNHCmdWindowClass;
|
|
|
|
if (!RegisterClass(&wcex)) {
|
|
panic("cannot register Map window class");
|
|
}
|
|
|
|
/* create default command set */
|
|
nhcmdset_current = nhcmdset_default = nhcmdset_create();
|
|
|
|
#ifdef WIN_CE_SMARTPHONE
|
|
plt = nhcmdlayout_create("General", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
|
|
nhcmdlayout_init(plt, cells_layout_general);
|
|
nhcmdset_add(nhcmdset_current, plt);
|
|
|
|
plt = nhcmdlayout_create("Movement", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
|
|
nhcmdlayout_init(plt, cells_layout_movement);
|
|
nhcmdset_add(nhcmdset_current, plt);
|
|
|
|
plt = nhcmdlayout_create("Attack", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
|
|
nhcmdlayout_init(plt, cells_layout_attack);
|
|
nhcmdset_add(nhcmdset_current, plt);
|
|
|
|
plt = nhcmdlayout_create("Item Handling", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
|
|
nhcmdlayout_init(plt, cells_layout_item_handling);
|
|
nhcmdset_add(nhcmdset_current, plt);
|
|
|
|
plt = nhcmdlayout_create("Game Controls", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
|
|
nhcmdlayout_init(plt, cells_layout_game);
|
|
nhcmdset_add(nhcmdset_current, plt);
|
|
|
|
plt = nhcmdlayout_create("Advanced Movement", NH_CMDPAD_ROWS,
|
|
NH_CMDPAD_COLS);
|
|
nhcmdlayout_init(plt, cells_layout_adv_movement);
|
|
nhcmdset_add(nhcmdset_current, plt);
|
|
|
|
plt = nhcmdlayout_create("Item Lookup", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
|
|
nhcmdlayout_init(plt, cells_layout_lookup);
|
|
nhcmdset_add(nhcmdset_current, plt);
|
|
|
|
if (wizard) {
|
|
plt =
|
|
nhcmdlayout_create("Wizard Mode", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
|
|
nhcmdlayout_init(plt, cells_layout_wizard);
|
|
nhcmdset_add(nhcmdset_current, plt);
|
|
}
|
|
|
|
#else /* ! WIN_CE_SMARTPHONE */
|
|
plt = nhcmdlayout_create("lowercase", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
|
|
nhcmdlayout_init(plt, cells_layout_mod1);
|
|
nhcmdset_add(nhcmdset_current, plt);
|
|
|
|
plt = nhcmdlayout_create("uppercase", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
|
|
nhcmdlayout_init(plt, cells_layout_mod2);
|
|
nhcmdset_add(nhcmdset_current, plt);
|
|
#endif /* WIN_CE_SMARTPHONE */
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
LRESULT CALLBACK
|
|
NHCommandWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PNHCmdWindow data;
|
|
int i;
|
|
|
|
switch (message) {
|
|
case WM_CREATE:
|
|
onCreate(hWnd, wParam, lParam);
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
onPaint(hWnd);
|
|
break;
|
|
|
|
case WM_SIZE:
|
|
LayoutCmdWindow(hWnd);
|
|
break;
|
|
|
|
case WM_LBUTTONDOWN:
|
|
onMouseDown(hWnd, wParam, lParam);
|
|
return 0;
|
|
|
|
case WM_MOUSEMOVE:
|
|
/* proceed only if if have mouse focus (set in onMouseDown() -
|
|
left mouse button is pressed) */
|
|
if (GetCapture() == hWnd) {
|
|
onMouseMove(hWnd, wParam, lParam);
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
break;
|
|
|
|
case WM_LBUTTONUP:
|
|
/* proceed only if if have mouse focus (set in onMouseDown()) */
|
|
if (GetCapture() == hWnd) {
|
|
onMouseUp(hWnd, wParam, lParam);
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
|
|
for (i = 0; i <= NH_CMDPAD_FONT_MAX; i++)
|
|
if (data->font[i])
|
|
DeleteObject(data->font[i]);
|
|
free(data);
|
|
SetWindowLong(hWnd, GWL_USERDATA, (LONG) 0);
|
|
break;
|
|
|
|
default:
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
}
|
|
return FALSE;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
onPaint(HWND hWnd)
|
|
{
|
|
PNHCmdWindow data;
|
|
PAINTSTRUCT ps;
|
|
HDC hDC;
|
|
int x, y;
|
|
TCHAR wbuf[BUFSZ];
|
|
HGDIOBJ saveFont;
|
|
BITMAP bm;
|
|
int cell_index;
|
|
|
|
/* get window data */
|
|
data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
|
|
|
|
hDC = BeginPaint(hWnd, &ps);
|
|
|
|
if (!IsRectEmpty(&ps.rcPaint)) {
|
|
HGDIOBJ oldBr;
|
|
HBRUSH hbrPattern;
|
|
COLORREF OldBg, OldFg;
|
|
HPEN hPen;
|
|
HGDIOBJ hOldPen;
|
|
|
|
saveFont = SelectObject(hDC, data->font[NH_CMDPAD_FONT_NORMAL]);
|
|
OldBg = SetBkColor(hDC, mswin_get_color(NHW_KEYPAD, MSWIN_COLOR_BG));
|
|
OldFg =
|
|
SetTextColor(hDC, mswin_get_color(NHW_KEYPAD, MSWIN_COLOR_FG));
|
|
|
|
GetObject(data->images, sizeof(BITMAP), (LPVOID) &bm);
|
|
|
|
hbrPattern = CreatePatternBrush(data->images);
|
|
hPen = CreatePen(PS_SOLID, 1,
|
|
mswin_get_color(NHW_KEYPAD, MSWIN_COLOR_FG));
|
|
|
|
for (x = 0, cell_index = 0;
|
|
x < nhcmdlayout_rows(data->layout_current); x++)
|
|
for (y = 0; y < nhcmdlayout_columns(data->layout_current);
|
|
y++, cell_index++) {
|
|
RECT cell_rt;
|
|
POINT pt[5];
|
|
PNHCmdPadCell p_cell_data;
|
|
|
|
p_cell_data =
|
|
nhcmdlayout_cell_direct(data->layout_current, cell_index);
|
|
|
|
/* calculate the cell rectangle */
|
|
cell_rt.left = data->cells[cell_index].orig.x;
|
|
cell_rt.top = data->cells[cell_index].orig.y;
|
|
cell_rt.right = data->cells[cell_index].orig.x
|
|
+ data->cell_size.cx * p_cell_data->mult;
|
|
cell_rt.bottom =
|
|
data->cells[cell_index].orig.y + data->cell_size.cy;
|
|
|
|
/* draw border */
|
|
hOldPen = SelectObject(hDC, hPen);
|
|
pt[0].x = cell_rt.left;
|
|
pt[0].y = cell_rt.top;
|
|
pt[1].x = cell_rt.right;
|
|
pt[1].y = cell_rt.top;
|
|
pt[2].x = cell_rt.right;
|
|
pt[2].y = cell_rt.bottom;
|
|
pt[3].x = cell_rt.left;
|
|
pt[3].y = cell_rt.bottom;
|
|
pt[4].x = cell_rt.left;
|
|
pt[4].y = cell_rt.top;
|
|
Polyline(hDC, pt, 5);
|
|
SelectObject(hDC, hOldPen);
|
|
|
|
/* calculate clipping rectangle for the text */
|
|
cell_rt.left++;
|
|
cell_rt.top++;
|
|
cell_rt.right--;
|
|
cell_rt.bottom--;
|
|
|
|
/* draw the cell text */
|
|
if (p_cell_data->image <= 0) {
|
|
SelectObject(hDC, data->font[-p_cell_data->image]);
|
|
DrawText(hDC, NH_A2W(p_cell_data->text, wbuf, BUFSZ),
|
|
strlen(p_cell_data->text), &cell_rt,
|
|
DT_CENTER | DT_VCENTER | DT_SINGLELINE
|
|
| DT_NOPREFIX);
|
|
} else {
|
|
/* draw bitmap */
|
|
int bmOffset;
|
|
RECT bitmap_rt;
|
|
|
|
bmOffset = (p_cell_data->image - 1) * bm.bmHeight;
|
|
|
|
bitmap_rt.left =
|
|
((cell_rt.left + cell_rt.right)
|
|
- min(bm.bmHeight, (cell_rt.right - cell_rt.left)))
|
|
/ 2;
|
|
bitmap_rt.top =
|
|
((cell_rt.bottom + cell_rt.top)
|
|
- min(bm.bmHeight, (cell_rt.bottom - cell_rt.top)))
|
|
/ 2;
|
|
bitmap_rt.right =
|
|
bitmap_rt.left
|
|
+ min(bm.bmHeight, (cell_rt.right - cell_rt.left));
|
|
bitmap_rt.bottom =
|
|
bitmap_rt.top
|
|
+ min(bm.bmHeight, (cell_rt.bottom - cell_rt.top));
|
|
|
|
SetBrushOrgEx(hDC, bitmap_rt.left - bmOffset,
|
|
bitmap_rt.top, NULL);
|
|
oldBr = SelectObject(hDC, hbrPattern);
|
|
PatBlt(hDC, bitmap_rt.left, bitmap_rt.top,
|
|
bitmap_rt.right - bitmap_rt.left,
|
|
bitmap_rt.bottom - bitmap_rt.top, PATCOPY);
|
|
SelectObject(hDC, oldBr);
|
|
}
|
|
|
|
/* invert the cell if it is selected */
|
|
if (data->cells[cell_index].state == NH_CST_CHECKED) {
|
|
IntersectRect(&cell_rt, &cell_rt, &ps.rcPaint);
|
|
PatBlt(hDC, cell_rt.left, cell_rt.top,
|
|
cell_rt.right - cell_rt.left,
|
|
cell_rt.bottom - cell_rt.top, DSTINVERT);
|
|
}
|
|
}
|
|
|
|
SetTextColor(hDC, OldFg);
|
|
SetBkColor(hDC, OldBg);
|
|
SelectObject(hDC, saveFont);
|
|
DeleteObject(hbrPattern);
|
|
DeleteObject(hPen);
|
|
}
|
|
EndPaint(hWnd, &ps);
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PNHCmdWindow data;
|
|
|
|
/* set window data */
|
|
data = (PNHCmdWindow) malloc(sizeof(NHCmdWindow));
|
|
if (!data)
|
|
panic("out of memory");
|
|
|
|
ZeroMemory(data, sizeof(NHCmdWindow));
|
|
SetWindowLong(hWnd, GWL_USERDATA, (LONG) data);
|
|
|
|
data->active_cell = -1;
|
|
|
|
/* load images bitmap */
|
|
data->images = LoadBitmap(GetNHApp()->hApp, MAKEINTRESOURCE(IDB_KEYPAD));
|
|
if (!data->images)
|
|
panic("cannot load keypad bitmap");
|
|
|
|
/* create default layouts */
|
|
data->layout_current = 0;
|
|
data->layout_save = 0;
|
|
data->cells = 0;
|
|
|
|
#if defined(WIN_CE_SMARTPHONE)
|
|
data->layout_selected = nhcmdset_get(nhcmdset_current, 0);
|
|
#endif
|
|
|
|
/* set default layout */
|
|
SetCmdWindowLayout(hWnd, nhcmdset_get(nhcmdset_current, 0));
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
LayoutCmdWindow(HWND hWnd)
|
|
{
|
|
RECT clrt;
|
|
SIZE windowSize;
|
|
PNHCmdWindow data;
|
|
int i, j;
|
|
int x, y;
|
|
LOGFONT lgfnt;
|
|
int index;
|
|
|
|
GetClientRect(hWnd, &clrt);
|
|
if (IsRectEmpty(&clrt))
|
|
return;
|
|
|
|
data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
|
|
if (!data->layout_current)
|
|
return;
|
|
|
|
/* calculate cell size */
|
|
windowSize.cx = clrt.right - clrt.left;
|
|
windowSize.cy = clrt.bottom - clrt.top;
|
|
CalculateCellSize(hWnd, &data->cell_size, &windowSize);
|
|
|
|
/* initialize display cells aray */
|
|
x = 0;
|
|
y = 0;
|
|
for (i = 0, index = 0; i < nhcmdlayout_rows(data->layout_current); i++) {
|
|
for (j = 0; j < nhcmdlayout_columns(data->layout_current);
|
|
j++, index++) {
|
|
data->cells[index].orig.x = x;
|
|
data->cells[index].orig.y = y;
|
|
data->cells[index].type =
|
|
nhcmdlayout_cell_direct(data->layout_current, index)->type;
|
|
|
|
switch (data->cells[index].type) {
|
|
case NH_CELL_CTRL:
|
|
data->cells[index].state = data->is_ctrl ? NH_CST_CHECKED : 0;
|
|
break;
|
|
case NH_CELL_CAP:
|
|
data->cells[index].state = data->is_caps ? NH_CST_CHECKED : 0;
|
|
break;
|
|
case NH_CELL_SHIFT:
|
|
data->cells[index].state =
|
|
data->is_shift ? NH_CST_CHECKED : 0;
|
|
break;
|
|
default:
|
|
data->cells[index].state = 0;
|
|
}
|
|
|
|
x += data->cell_size.cx
|
|
* nhcmdlayout_cell_direct(data->layout_current, index)->mult;
|
|
}
|
|
x = 0;
|
|
y += data->cell_size.cy;
|
|
}
|
|
|
|
/* create font for display cell text */
|
|
for (i = 0; i <= NH_CMDPAD_FONT_MAX; i++)
|
|
if (data->font[i])
|
|
DeleteObject(data->font[i]);
|
|
|
|
ZeroMemory(&lgfnt, sizeof(lgfnt));
|
|
lgfnt.lfHeight = data->cell_size.cy; // height of font
|
|
lgfnt.lfWidth = 0; // average character width
|
|
lgfnt.lfEscapement = 0; // angle of escapement
|
|
lgfnt.lfOrientation = 0; // base-line orientation angle
|
|
lgfnt.lfWeight = FW_NORMAL; // font weight
|
|
lgfnt.lfItalic = FALSE; // italic attribute option
|
|
lgfnt.lfUnderline = FALSE; // underline attribute option
|
|
lgfnt.lfStrikeOut = FALSE; // strikeout attribute option
|
|
lgfnt.lfCharSet = ANSI_CHARSET; // character set identifier
|
|
lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS; // output precision
|
|
lgfnt.lfClipPrecision = CLIP_CHARACTER_PRECIS; // clipping precision
|
|
lgfnt.lfQuality = DEFAULT_QUALITY; // output quality
|
|
if (iflags.wc_font_message && *iflags.wc_font_message) {
|
|
lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
|
|
NH_A2W(iflags.wc_font_message, lgfnt.lfFaceName, LF_FACESIZE);
|
|
} else {
|
|
lgfnt.lfPitchAndFamily = VARIABLE_PITCH; // pitch and family
|
|
}
|
|
data->font[NH_CMDPAD_FONT_NORMAL] = CreateFontIndirect(&lgfnt);
|
|
|
|
InvalidateRect(hWnd, NULL, TRUE);
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
SetCmdWindowLayout(HWND hWnd, PNHCmdLayout layout)
|
|
{
|
|
PNHCmdWindow data;
|
|
int size;
|
|
|
|
data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
|
|
if (data->layout_current == layout)
|
|
return;
|
|
|
|
data->layout_current = layout;
|
|
size = sizeof(NHCmdPadLayoutCell) * nhcmdlayout_rows(layout)
|
|
* nhcmdlayout_columns(layout);
|
|
data->cells = (PNHCmdPadLayoutCell) realloc(data->cells, size);
|
|
ZeroMemory(data->cells, size);
|
|
LayoutCmdWindow(hWnd);
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
onMouseDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PNHCmdWindow data;
|
|
POINT mpt;
|
|
|
|
/* get mouse coordinates */
|
|
mpt.x = LOWORD(lParam);
|
|
mpt.y = HIWORD(lParam);
|
|
|
|
/* map mouse coordinates to the display cell */
|
|
data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
|
|
data->active_cell = CellFromPoint(data, mpt);
|
|
if (data->active_cell == -1)
|
|
return;
|
|
|
|
/* set mouse focus to the current window */
|
|
SetCapture(hWnd);
|
|
|
|
/* invert the selection */
|
|
HighlightCell(hWnd, data->active_cell,
|
|
(data->cells[data->active_cell].state != NH_CST_CHECKED));
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
onMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PNHCmdWindow data;
|
|
POINT mpt;
|
|
int newActiveCell;
|
|
|
|
/* get mouse coordinates */
|
|
mpt.x = LOWORD(lParam);
|
|
mpt.y = HIWORD(lParam);
|
|
|
|
/* map mouse coordinates to the display cell */
|
|
data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
|
|
newActiveCell = CellFromPoint(data, mpt);
|
|
if (data->active_cell == -1)
|
|
return;
|
|
|
|
/* if mouse is within orginal display cell - select the cell otherwise
|
|
clear the selection */
|
|
switch (nhcmdlayout_cell_direct(data->layout_current, data->active_cell)
|
|
->type) {
|
|
case NH_CELL_REG:
|
|
HighlightCell(hWnd, data->active_cell,
|
|
(newActiveCell == data->active_cell));
|
|
break;
|
|
|
|
case NH_CELL_CTRL:
|
|
HighlightCell(hWnd, data->active_cell,
|
|
((newActiveCell == data->active_cell) ? !data->is_ctrl
|
|
: data->is_ctrl));
|
|
break;
|
|
|
|
case NH_CELL_CAP:
|
|
HighlightCell(hWnd, data->active_cell,
|
|
((newActiveCell == data->active_cell) ? !data->is_caps
|
|
: data->is_caps));
|
|
break;
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
onMouseUp(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PNHCmdWindow data;
|
|
|
|
/* release mouse capture */
|
|
ReleaseCapture();
|
|
|
|
/* get active display cell */
|
|
data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
|
|
if (data->active_cell == -1)
|
|
return;
|
|
|
|
ActivateCell(hWnd, data->active_cell);
|
|
|
|
data->active_cell = -1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
ActivateCell(HWND hWnd, int cell)
|
|
{
|
|
PNHCmdWindow data;
|
|
PNHCmdPadCell p_cell_data;
|
|
int i;
|
|
|
|
data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
|
|
if (!data)
|
|
return;
|
|
p_cell_data = nhcmdlayout_cell_direct(data->layout_current, cell);
|
|
|
|
/* act depending on the cell type:
|
|
CAPS - change layout
|
|
CTRL - modify CTRL status
|
|
REG - place keyboard event on the nethack input queue
|
|
*/
|
|
switch (p_cell_data->type) {
|
|
case NH_CELL_REG:
|
|
if (data->is_ctrl) {
|
|
PushNethackCommand(p_cell_data->f_char, 1);
|
|
|
|
data->is_ctrl = 0;
|
|
for (i = 0; i < nhcmdlayout_rows(data->layout_current)
|
|
* nhcmdlayout_columns(data->layout_current);
|
|
i++) {
|
|
if (nhcmdlayout_cell_direct(data->layout_current, i)->type
|
|
== NH_CELL_CTRL) {
|
|
HighlightCell(hWnd, i, data->is_ctrl);
|
|
}
|
|
}
|
|
} else {
|
|
PushNethackCommand(p_cell_data->f_char, 0);
|
|
}
|
|
HighlightCell(hWnd, cell, FALSE);
|
|
|
|
// select a new layout if present
|
|
i = (int) p_cell_data->data;
|
|
if (i == -1) {
|
|
if (data->layout_save)
|
|
SetCmdWindowLayout(hWnd, data->layout_save);
|
|
data->layout_save = NULL;
|
|
} else {
|
|
if (!data->layout_save)
|
|
data->layout_save = data->layout_current;
|
|
SetCmdWindowLayout(hWnd, nhcmdset_get(nhcmdset_current, i));
|
|
}
|
|
|
|
if (!data->is_shift)
|
|
break;
|
|
// else fall through and reset the shift
|
|
|
|
case NH_CELL_SHIFT:
|
|
data->is_shift = !data->is_shift;
|
|
SetCmdWindowLayout(hWnd, (data->is_shift ^ data->is_caps)
|
|
? nhcmdset_get(nhcmdset_current, 1)
|
|
: nhcmdset_get(nhcmdset_current, 0));
|
|
data->cells[cell].state = data->is_shift ? NH_CST_CHECKED : 0;
|
|
InvalidateRect(hWnd, NULL, TRUE);
|
|
break;
|
|
|
|
case NH_CELL_CTRL:
|
|
data->is_ctrl = !data->is_ctrl;
|
|
HighlightCell(hWnd, cell, data->is_ctrl);
|
|
break;
|
|
|
|
case NH_CELL_CAP:
|
|
data->is_caps = !data->is_caps;
|
|
SetCmdWindowLayout(hWnd, (data->is_shift ^ data->is_caps)
|
|
? nhcmdset_get(nhcmdset_current, 1)
|
|
: nhcmdset_get(nhcmdset_current, 0));
|
|
data->cells[cell].state = data->is_caps ? NH_CST_CHECKED : 0;
|
|
InvalidateRect(hWnd, NULL, TRUE);
|
|
break;
|
|
|
|
case NH_CELL_LAYOUT_NEW: {
|
|
PNHCmdLayout pLayout;
|
|
|
|
HighlightCell(hWnd, cell, FALSE);
|
|
|
|
pLayout = (PNHCmdLayout) p_cell_data->data;
|
|
if (pLayout) {
|
|
SetCmdWindowLayout(hWnd, pLayout);
|
|
}
|
|
} break;
|
|
|
|
case NH_CELL_LAYOUT_MENU: {
|
|
winid wid;
|
|
int i;
|
|
anything any;
|
|
menu_item *selected = 0;
|
|
PNHCmdSet pSet;
|
|
|
|
HighlightCell(hWnd, cell, FALSE);
|
|
|
|
pSet = (PNHCmdSet) p_cell_data->data;
|
|
if (!pSet)
|
|
pSet = nhcmdset_default;
|
|
|
|
wid = mswin_create_nhwindow(NHW_MENU);
|
|
mswin_start_menu(wid);
|
|
for (i = 0; i < nhcmdset_count(pSet); i++) {
|
|
any.a_void = nhcmdset_get(pSet, i);
|
|
mswin_add_menu(wid, NO_GLYPH, &any, 'a' + i, 0, ATR_NONE,
|
|
nhcmdset_get_name(pSet, i), FALSE);
|
|
}
|
|
mswin_end_menu(wid, "Select keypad layout");
|
|
i = select_menu(wid, PICK_ONE, &selected);
|
|
mswin_destroy_nhwindow(wid);
|
|
|
|
if (i == 1) {
|
|
#if defined(WIN_CE_SMARTPHONE)
|
|
data->layout_selected = (PNHCmdLayout) selected[0].item.a_void;
|
|
#endif
|
|
SetCmdWindowLayout(hWnd, (PNHCmdLayout) selected[0].item.a_void);
|
|
}
|
|
} break;
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
int
|
|
CellFromPoint(PNHCmdWindow data, POINT pt)
|
|
{
|
|
int i;
|
|
for (i = 0; i < nhcmdlayout_rows(data->layout_current)
|
|
* nhcmdlayout_columns(data->layout_current);
|
|
i++) {
|
|
RECT cell_rt;
|
|
cell_rt.left = data->cells[i].orig.x;
|
|
cell_rt.top = data->cells[i].orig.y;
|
|
cell_rt.right =
|
|
data->cells[i].orig.x
|
|
+ data->cell_size.cx
|
|
* nhcmdlayout_cell_direct(data->layout_current, i)->mult;
|
|
cell_rt.bottom = data->cells[i].orig.y + data->cell_size.cy;
|
|
if (PtInRect(&cell_rt, pt))
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
CalculateCellSize(HWND hWnd, LPSIZE pSize, LPSIZE pWindowSize)
|
|
{
|
|
HDC hdc;
|
|
PNHCmdWindow data;
|
|
data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
|
|
if (!data)
|
|
return;
|
|
|
|
hdc = GetDC(hWnd);
|
|
|
|
/* if windows size is specified - attempt ro stretch cells across
|
|
the the window size. If not - make default cell size based on
|
|
10 points font. Make sure that cell cesize does not exceeds 20 points
|
|
*/
|
|
if (pWindowSize->cx > 0)
|
|
pSize->cx =
|
|
pWindowSize->cx / nhcmdlayout_columns(data->layout_current);
|
|
else
|
|
pSize->cx = 10 * GetDeviceCaps(hdc, LOGPIXELSX) / 72;
|
|
pSize->cx = min(pSize->cx, 20 * GetDeviceCaps(hdc, LOGPIXELSX) / 72);
|
|
|
|
if (pWindowSize->cy > 0)
|
|
pSize->cy = pWindowSize->cy / nhcmdlayout_rows(data->layout_current);
|
|
else
|
|
pSize->cy = 10 * GetDeviceCaps(hdc, LOGPIXELSY) / 72;
|
|
pSize->cy = min(pSize->cy, 20 * GetDeviceCaps(hdc, LOGPIXELSY) / 72);
|
|
|
|
ReleaseDC(hWnd, hdc);
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
HighlightCell(HWND hWnd, int cell, BOOL isSelected)
|
|
{
|
|
HDC hDC;
|
|
PNHCmdWindow data;
|
|
int prevState;
|
|
|
|
data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
|
|
prevState = data->cells[cell].state;
|
|
data->cells[cell].state = (isSelected) ? NH_CST_CHECKED : 0;
|
|
|
|
if (prevState != data->cells[cell].state) {
|
|
hDC = GetDC(hWnd);
|
|
PatBlt(hDC, data->cells[cell].orig.x + 1,
|
|
data->cells[cell].orig.y + 1,
|
|
data->cell_size.cx
|
|
* nhcmdlayout_cell_direct(data->layout_current, cell)
|
|
->mult
|
|
- 2,
|
|
data->cell_size.cy - 2, DSTINVERT);
|
|
ReleaseDC(hWnd, hDC);
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
PushNethackCommand(const char *cmd_char_str, int is_ctrl)
|
|
{
|
|
while (*cmd_char_str) {
|
|
if (is_ctrl) {
|
|
NHEVENT_KBD(C(*cmd_char_str));
|
|
} else {
|
|
NHEVENT_KBD(*cmd_char_str);
|
|
}
|
|
cmd_char_str++;
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
/*------------------- keyboard keys layout functions ----------------------*/
|
|
/*-------------------------------------------------------------------------*/
|
|
PNHCmdLayout
|
|
nhcmdlayout_create(const char *name, int rows, int columns)
|
|
{
|
|
PNHCmdLayout p;
|
|
int i;
|
|
|
|
i = sizeof(NHCmdLayout) + rows * columns * sizeof(NHCmdPadCell);
|
|
p = (PNHCmdLayout) malloc(i);
|
|
ZeroMemory(p, i);
|
|
p->rows = rows;
|
|
p->columns = columns;
|
|
strncpy(p->name, name, sizeof(p->name) - 1);
|
|
for (i = 0; i < rows * columns; i++) {
|
|
p->cells[i].cmd_code = -1;
|
|
p->cells[i].image = -NH_CMDPAD_FONT_NORMAL;
|
|
p->cells[i].type = 1;
|
|
p->cells[i].mult = 1;
|
|
}
|
|
return p;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
nhcmdlayout_init(PNHCmdLayout p, PNHCmdPadCell cells)
|
|
{
|
|
memcpy(p->cells, cells, p->rows * p->columns * sizeof(NHCmdPadCell));
|
|
}
|
|
|
|
void
|
|
nhcmdlayout_destroy(PNHCmdLayout p)
|
|
{
|
|
free(p);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
/*----------------- keyboard keys layout set functions --------------------*/
|
|
/*-------------------------------------------------------------------------*/
|
|
PNHCmdSet
|
|
nhcmdset_create()
|
|
{
|
|
PNHCmdSet p;
|
|
p = (PNHCmdSet) malloc(sizeof(NHCmdSet));
|
|
ZeroMemory(p, sizeof(NHCmdSet));
|
|
return p;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
int
|
|
nhcmdset_count(PNHCmdSet p)
|
|
{
|
|
assert(p);
|
|
return p->count;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
PNHCmdLayout
|
|
nhcmdset_get(PNHCmdSet p, int index)
|
|
{
|
|
assert(p);
|
|
assert(index >= 0 && index < p->count);
|
|
return p->elements[index].layout;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
const char *
|
|
nhcmdset_get_name(PNHCmdSet p, int index)
|
|
{
|
|
assert(p);
|
|
assert(index >= 0 && index < p->count);
|
|
return p->elements[index].layout->name;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
nhcmdset_add(PNHCmdSet p, PNHCmdLayout layout)
|
|
{
|
|
assert(p);
|
|
assert(p->count < NH_CMDSET_MAXSIZE);
|
|
p->elements[p->count].layout = layout;
|
|
p->elements[p->count].free_on_destroy = 0;
|
|
p->count++;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
nhcmdset_destroy(PNHCmdSet p)
|
|
{
|
|
int i = 0;
|
|
assert(p);
|
|
for (i = 0; i < p->count; i++) {
|
|
if (p->elements[i].free_on_destroy) {
|
|
nhcmdlayout_destroy(p->elements[i].layout);
|
|
}
|
|
}
|
|
free(p);
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
#if defined(WIN_CE_SMARTPHONE)
|
|
/* special keypad input handling for SmartPhone
|
|
the phone keypad maps to VK_* as shown below.
|
|
some keys might not be present, e.g. VK_TFLIP
|
|
sofkey1 softkey2 VK_TSOFT1, VK_TSOFT2
|
|
^ VK_TUP
|
|
< + > VK_TLEFT, VK_TACTION, VK_TRIGHT
|
|
v VK_TDOWN
|
|
home back VK_THOME, VK_TBACK
|
|
talk end VK_TTALK, VK_TEND
|
|
1 2 3 VK_T0..VK_T9
|
|
4 5 6 ...
|
|
7 8 9 ...
|
|
* 0 # VK_TSTAR, VK_TPOUND
|
|
other buttons include
|
|
VK_TRECORD
|
|
VK_TPOWER, VK_TVOLUMEUP, VK_TVOLUMEDOWN
|
|
VK_TFLIP
|
|
*/
|
|
BOOL
|
|
NHSPhoneTranslateKbdMessage(WPARAM wParam, LPARAM lParam, BOOL keyDown)
|
|
{
|
|
PNHCmdWindow data;
|
|
int index = -1;
|
|
|
|
/* get window data */
|
|
data = (PNHCmdWindow) GetWindowLong(GetNHApp()->hCmdWnd, GWL_USERDATA);
|
|
if (!data)
|
|
return FALSE;
|
|
|
|
switch (wParam) {
|
|
case VK_T0:
|
|
index = 10;
|
|
break;
|
|
|
|
case VK_T1:
|
|
index = 0;
|
|
break;
|
|
|
|
case VK_T2:
|
|
index = 1;
|
|
break;
|
|
|
|
case VK_T3:
|
|
index = 2;
|
|
break;
|
|
|
|
case VK_T4:
|
|
index = 3;
|
|
break;
|
|
|
|
case VK_T5:
|
|
index = 4;
|
|
break;
|
|
|
|
case VK_T6:
|
|
index = 5;
|
|
break;
|
|
|
|
case VK_T7:
|
|
index = 6;
|
|
break;
|
|
|
|
case VK_T8:
|
|
index = 7;
|
|
break;
|
|
|
|
case VK_T9:
|
|
index = 8;
|
|
break;
|
|
|
|
case VK_TSTAR:
|
|
index = 9;
|
|
break;
|
|
|
|
case VK_TPOUND:
|
|
index = 11;
|
|
break;
|
|
}
|
|
|
|
if (index >= 0) {
|
|
HighlightCell(GetNHApp()->hCmdWnd, index, keyDown);
|
|
if (keyDown)
|
|
ActivateCell(GetNHApp()->hCmdWnd, index);
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
NHSPhoneSetKeypadFromString(const char *str)
|
|
{
|
|
PNHCmdWindow data;
|
|
PNHCmdSet p = 0;
|
|
PNHCmdLayout layout_prev = 0;
|
|
PNHCmdLayout layout_cur = 0;
|
|
char buf[2][BUFSZ];
|
|
int i, lcount;
|
|
char *s;
|
|
|
|
assert(NH_CMDPAD_ROWS == 4);
|
|
|
|
data = (PNHCmdWindow) GetWindowLong(GetNHApp()->hCmdWnd, GWL_USERDATA);
|
|
if (!data)
|
|
return;
|
|
|
|
p = nhcmdset_create();
|
|
|
|
ZeroMemory(buf, sizeof(buf));
|
|
if (sscanf(str, "%s or %s", buf[1], buf[0]) != 2) {
|
|
ZeroMemory(buf, sizeof(buf));
|
|
strncpy(buf[0], str, sizeof(buf[0]) - 1);
|
|
}
|
|
|
|
lcount = 10; /* create new layout on the first iteration */
|
|
for (i = 0; i < 2; i++) {
|
|
s = buf[i];
|
|
while (*s) {
|
|
char c_start, c_end, c_char;
|
|
|
|
/* parse character ranges */
|
|
if (isalnum((c_start = s[0])) && s[1] == '-'
|
|
&& isalnum((c_end = s[2]))) {
|
|
s += 2;
|
|
} else {
|
|
c_start = c_end = *s;
|
|
}
|
|
|
|
for (c_char = c_start; c_char <= c_end; c_char++) {
|
|
if (lcount >= 10) {
|
|
/* create layout */
|
|
lcount = 0;
|
|
layout_prev = layout_cur;
|
|
layout_cur = nhcmdlayout_create("noname", NH_CMDPAD_ROWS,
|
|
NH_CMDPAD_COLS);
|
|
nhcmdlayout_init(layout_cur, cells_layout_menu);
|
|
|
|
nhcmdlayout_cell(layout_cur, 3, 0)->data = layout_prev;
|
|
nhcmdlayout_cell(layout_cur, 3, 2)->data = 0;
|
|
|
|
nhcmdset_add(p, layout_cur);
|
|
p->elements[p->count - 1].free_on_destroy = 1;
|
|
|
|
if (layout_prev) {
|
|
nhcmdlayout_cell(layout_prev, 3, 2)->data =
|
|
layout_cur;
|
|
}
|
|
}
|
|
|
|
if (lcount == 9)
|
|
lcount = 10; // skip '#'
|
|
nhcmdlayout_cell_direct(layout_cur, lcount)->f_char[0] =
|
|
c_char;
|
|
if (c_char == '\033') {
|
|
strcpy(nhcmdlayout_cell_direct(layout_cur, lcount)->text,
|
|
"esc");
|
|
nhcmdlayout_cell_direct(layout_cur, lcount)->image =
|
|
14; /* 14 is a ESC symbol in IDB_KEYPAD */
|
|
} else {
|
|
nhcmdlayout_cell_direct(layout_cur, lcount)->text[0] =
|
|
c_char;
|
|
nhcmdlayout_cell_direct(layout_cur, lcount)->text[1] =
|
|
'\x0';
|
|
}
|
|
|
|
/* increment character count in the current layout */
|
|
lcount++;
|
|
}
|
|
|
|
/* prepareg next charcter from the source string */
|
|
s++;
|
|
}
|
|
}
|
|
|
|
/* install the new set */
|
|
if (nhcmdset_current != nhcmdset_default)
|
|
nhcmdset_destroy(nhcmdset_current);
|
|
nhcmdset_current = p;
|
|
SetCmdWindowLayout(GetNHApp()->hCmdWnd,
|
|
nhcmdset_get(nhcmdset_current, 0));
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
NHSPhoneSetKeypadDirection()
|
|
{
|
|
PNHCmdWindow data;
|
|
|
|
data = (PNHCmdWindow) GetWindowLong(GetNHApp()->hCmdWnd, GWL_USERDATA);
|
|
if (!data)
|
|
return;
|
|
|
|
if (nhcmdset_current != nhcmdset_default)
|
|
nhcmdset_destroy(nhcmdset_current);
|
|
nhcmdset_current = nhcmdset_default;
|
|
SetCmdWindowLayout(GetNHApp()->hCmdWnd,
|
|
nhcmdset_get(nhcmdset_current, NH_LAYOUT_MOVEMENT));
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void
|
|
NHSPhoneSetKeypadDefault()
|
|
{
|
|
PNHCmdWindow data;
|
|
|
|
data = (PNHCmdWindow) GetWindowLong(GetNHApp()->hCmdWnd, GWL_USERDATA);
|
|
if (!data)
|
|
return;
|
|
|
|
if (nhcmdset_current != nhcmdset_default)
|
|
nhcmdset_destroy(nhcmdset_current);
|
|
nhcmdset_current = nhcmdset_default;
|
|
SetCmdWindowLayout(GetNHApp()->hCmdWnd,
|
|
data->layout_selected
|
|
? data->layout_selected
|
|
: nhcmdset_get(nhcmdset_current, 0));
|
|
}
|
|
|
|
#endif /* defined (WIN_CE_SMARTHPONE) */
|