mmicalculatormain.c
来自「是一个手机功能的模拟程序」· C语言 代码 · 共 788 行 · 第 1/2 页
C
788 行
// Create window handler
data->win = win_create (parent_window, 0, E_WIN_VISIBLE, NULL);
if (data->win EQ NULL)
{
return NULL;
}
// connect the dialog data to the MFW-window
data->mmi_control.dialog = (T_DIALOG_FUNC)calc_DialogCB;
data->mmi_control.data = data;
win = ((T_MFW_HDR *)data->win)->data;
win->user = (void *)data;
data->parent_win = parent_window;
calculator_win = data->win;
return data->win;
}
/*******************************************************************************
$Function: calc_DialogCB
$Description: Callback function for the calculator window
$Returns: nothing
$Arguments: Window, event, identifier (not used), parameter (not used)
*******************************************************************************/
static void calc_DialogCB(T_MFW_HND win, USHORT e, SHORT identifier, void *parameter)
{
T_MFW_WIN *win_data = ( (T_MFW_HDR *) win )->data;
tCalcData* data = (tCalcData *) win_data->user;
char display_buffer[28] = "";
T_EDITOR_DATA editor_data;
char* running_total_out;
char debug_buffer[50];
TRACE_FUNCTION("calc_DialogCB()");
switch( e )
{ //when window first created
case CALC_INIT:
{ //set running total to 0 and display in editor
TRACE_EVENT("CALC-INIT-JGG");
running_total = 0;
data->menu_options_win = NULL;
//sprintf(data->buffer, "%d", running_total);
//jgg
sprintf(data->buffer, "%s", "");
//jgg
calcSetEditor(win);//set editor with default attribute values
data->editor_data.Callback = (T_EDIT_CB)calcGetNumberCB;
data->editor_win = editor_start(win, &(data->editor_data)); /* start the editor */
winShow(data->win);
}
break;
//when an arithmetic operator has been selected from the calc menu
case CALC_ENTER_OPERAND:
{
TRACE_EVENT("CALC-ENTER-OPERAND-JGG");
//this memory alloc seems to fix a problem where running_total_out
//would become an empty string after sevarla running calculations
running_total_out = (char*)malloc(22*sizeof(char));
sprintf(debug_buffer, "Running Total: %s %f",running_total_out, calcGetRunningTotal());
TRACE_EVENT(debug_buffer);
//jgg
running_total_out[0] = '\0';
//jgg
//OK we display the first operand and the operator symbol
//above the operand to be entered
if ( (long)calcGetRunningTotal() == calcGetRunningTotal())
sprintf((char*)running_total_out, "%d", (long)calcGetRunningTotal());
else
sprintf((char*)running_total_out, "%f", calcGetRunningTotal());
if (running_total_out[8] == '.')
running_total_out[8] = '\0';
else
running_total_out[9] = '\0';
sprintf(debug_buffer, "Running Total: %s %f",running_total_out, calcGetRunningTotal());
TRACE_EVENT(debug_buffer);
sprintf((char*)display_buffer,"%s %c", running_total_out, operatorSymbol(data->operation));
TRACE_EVENT(display_buffer);
//jgg
//sprintf(data->buffer, "%d", 0);
sprintf(data->buffer, "%s", "");
//jgg
calcSetEditor(win);
data->editor_data.TextString = display_buffer;
data->editor_data.editor_attr.win.px = 0;
data->editor_data.editor_attr.win.py = 30;
data->editor_data.editor_attr.win.sx = 84;
data->editor_data.editor_attr.win.sy = 10;
data->editor_data.Callback = (T_EDIT_CB)calcGetOperandCB;
/*data->input_number_win =*/ editor_start(win, &(data->editor_data)); /* start the editor */
winShow(data->win);
free((void*)running_total_out);
}
break;
//when "Equals" selected from calc menu
case CALC_DISPLAY_RESULT:
{
TRACE_EVENT("CALC-DISPLAY-RESULT-JGG");
//if running total out of display range, set it to 0
if ((calcGetRunningTotal() > MAX_CALC_TOTAL) || (calcGetRunningTotal() < MIN_CALC_TOTAL))
running_total =0;
//Convert running total double to string
//if integer total, don't display any decimal places
if ( (long)calcGetRunningTotal() == calcGetRunningTotal())
sprintf(data->buffer, "%d", (long) calcGetRunningTotal());
else //if a floating-point total, display as many decimal places as will fit
sprintf(data->buffer, "%f", (double) calcGetRunningTotal());
//if last number in display is a decimal point
if (data->buffer[8] == '.')
data->buffer[8] = '\0';//remove it
data->buffer[9] = '\0'; //ensure string is properly terminated
//ensure string is no longer than 9 chars
calcSetEditor(win);
data->editor_data.Callback = (T_EDIT_CB)calcGetNumberCB;
/*data->input_number_win =*/ editor_start(win, &(data->editor_data)); /* start the editor */
winShow(data->win);
}
break;
default:
{
TRACE_EVENT("calc_DialogCB(): Unknown Event");
}
break;
}
}
/*******************************************************************************
$Function: calcGetNumberCB
$Description: Callback function for the editor window
$Returns: nothing
$Arguments: Window, identifier (not used), reason (not used)
*******************************************************************************/
static void calcGetNumberCB( T_MFW_HND win, USHORT Identifier,UBYTE reason)
{
T_MFW_WIN *win_data = ( (T_MFW_HDR *) win )->data;
tCalcData *data = (tCalcData *) win_data->user;
float after_decimal = 0;
int digits_after_point = 0;
int i;
char* end;
char debug[40];
TRACE_FUNCTION("calcGetNumberCB()");
switch (reason )
{
case INFO_KCD_LEFT:
{ TRACE_EVENT("Left button pressed in calculator");
//get the number entered before the decimal point
running_total = strtol(data->buffer, &end, 10);
if (strlen(end) != 0)
{ //if decimal point entered
if ((end[0] == '.') && isdigit(end[1]))//get number after decimal point
{
end++;
digits_after_point = strlen(end);
after_decimal = strtol(end, &end, 10);
}
//convert number after decimal point to it's actual fractional value
for (i=0; i < digits_after_point; i++)
after_decimal = after_decimal/10;
//add whole number and fraction together
running_total = running_total + after_decimal;
}
if (data->menu_options_win != NULL)
bookMenuDestroy( data->menu_options_win );
//start the calculator option menu and kill this window
data->menu_options_win = bookMenuStart( data->win, calcOptionMenuAttributes(),0);
SEND_EVENT(data->menu_options_win, ADD_CALLBACK, NULL, (void *)calc_menu_cb);
}
break;
case INFO_KCD_HUP:
case INFO_KCD_RIGHT:
{
TRACE_EVENT("Right button pressed in calculator");
calc_destroy(win);
}
break;
default:
{
/* otherwise no action to be performed
*/
calc_destroy(win);
break;
}
}
}
/*******************************************************************************
$Function: calcGetOperandCB
$Description: Callback function for the editor window, when second number in operation
is entered.
$Returns: nothing
$Arguments: Window, identifier (not used), reason (not used)
*******************************************************************************/
static void calcGetOperandCB( T_MFW_HND win, USHORT Identifier,UBYTE reason)
{
T_MFW_WIN *win_data = ( (T_MFW_HDR *) win )->data;
tCalcData *data = (tCalcData *) win_data->user;
char* buffer;
float operand = 0;
float after_decimal = 0;
int digits_after_point = 0;
int i;
//long integer_running_total = 0;
char* end;
char debug[40];
TRACE_FUNCTION("calcGetNumberCB()");
switch (reason )
{
case INFO_KCD_LEFT:
{ //Get whole number before decimal point
operand = strtol(data->buffer, &end, 10);
//if buffer not pointing at an empty string now
if (strlen(end) != 0)
{ //if decimal point entered
if ((end[0] == '.') && isdigit(end[1]))//get number after decimal point
{
end++;
digits_after_point = strlen(end);
after_decimal = strtol(end, &end, 10);
sprintf(debug,"Digits after decimal: %f.", after_decimal);
}
//convert number after decimal point to an appropriate fraction
for (i=0; i < digits_after_point; i++)
after_decimal = after_decimal/10;
//add whole and fraction together
operand = operand + after_decimal;
}
//perform the arithmetic function requested
switch (data->operation)
{
case PLUS: running_total = running_total + operand; break;
case MINUS: running_total = running_total - operand;break;
case MULTIPLY: running_total = running_total * operand;break;
case DIVIDE: running_total = running_total / operand;break;
default: TRACE_EVENT("Unknown calc operation"); break;
}
//Show option menu
if (data->menu_options_win != NULL)
bookMenuDestroy( data->menu_options_win );
data->menu_options_win = bookMenuStart( data->win, calcOptionMenuAttributes(),0);
//calc_destroy(win);
}
break;
case INFO_KCD_HUP:
case INFO_KCD_RIGHT:
{
TRACE_EVENT("Right button pressed in calculator");
calc_destroy(win);
}
break;
default:
{
/* otherwise no action to be performed
*/
break;
}
}
}
static void calc_menu_cb(T_MFW_HND parent_win, UBYTE identifier, UBYTE reason)
{
T_MFW_WIN *win_data = ( (T_MFW_HDR *) parent_win )->data;
tCalcData* data = (tCalcData *) win_data->user;
//set menu window to NULL to prevent any dealloc problems
data->menu_options_win = NULL;
calc_destroy(parent_win);
}
/*******************************************************************************
$Function: calcSetEditor
$Description: Sets the editor attributes to defaults for the calculator module
$Returns: nothing
$Arguments: Window
*******************************************************************************/
void calcSetEditor(T_MFW_HND win)
{
T_MFW_WIN *win_data = ( (T_MFW_HDR *) win )->data;
tCalcData* data = (tCalcData *) win_data->user;
editor_attr_init(&((data->editor_data).editor_attr), NULL, edtCurBar1, 0, 0, 0);
data->editor_data.hide = FALSE;
data->editor_data.min_enter = 1; // Avoid returning empty strings
data->editor_data.Identifier = 0xFFFF ;
data->editor_data.TextString = NULL;
data->editor_data.timeout = FOREVER; // Avoid returning empty strings
data->editor_data.destroyEditor = TRUE;
data->editor_data.editor_attr.text = (char *)data->buffer;
data->editor_data.editor_attr.size = 10;
data->editor_data.TextId = '\0';
data->editor_data.LeftSoftKey = TxtSoftOptions;
data->editor_data.AlternateLeftSoftKey = TxtNull;
data->editor_data.RightSoftKey = TxtDelete;
data->editor_data.mode = CALC_MODE;
}
/*******************************************************************************
$Function: calc_destroy
$Description: Destroys the calculator editor window and frees up memory
$Returns: nothing
$Arguments: Window
*******************************************************************************/
void calc_destroy(MfwHnd own_window)
{
T_MFW_WIN * win_data;
tCalcData * data = NULL;
if (own_window)
{
win_data = ((T_MFW_HDR *)own_window)->data;
if (win_data != NULL) //PATCH TB
data = (tCalcData *)win_data->user;
if (data)
{
TRACE_EVENT ("calc_destroy()");
win_delete (data->win);
// Free Memory
FREE_MEMORY ((void *)data, sizeof (tCalcData));
}
else
{
TRACE_EVENT ("calc_destroy() called twice");
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?