emWin ダイアログボックス

 

ダイアログボックス

 入力

ウィンドウマネージャーはタッチスクリーン、マウスやキーボードなどで最後に選択されたウィンドウを記憶しています。そして最後に選択されているウィンドウを入力待機状態(input focus)にします。

 

ブロッキング、ノンブロッキング
ブロッキングダイアログはユーザーがダイアログボックスに要求された操作を完了しクローズするまでプログラム本体の操作ができなくなるものです。一方ノンブロッキングダイアログはダイアログ表示中もプログラム本体の操作が引き続き可能なものです。
ブロッキングはモーダル、ノンブロッキングはモードレスと表現されることもあります。

 

ダイアログプロシージャ
ダイアログはひとつのウィンドウであり、他のウインドウと同様にメッセージを受け取ります。ほとんどのメッセージはダイアログボックスのコールバックルーチンによって自動的に扱われています。それ以外のメッセージはダイアログプロシージャに初期値を与えるために使用します。次で詳しく説明しています。

 

ダイアログメッセージ
ダイアログプロシージャに送られる2種類の追加メッセージが有ります(WM_INIT_DIALOG と WM_NOTIFY_PARENT)。WM_INIT_DIALOG メッセージはダイアログボックスが表示される前にダイアログプロシージャに送られます。ダイアログプロシージャはダイアログボックスのデザインや構成するウィジットなどを初期化するためにこのメッセージを使用します。次に、WM_NOTIFY_PARENTメッセージは子ウィンドウから親ウィンドウへのイベント発生の通知を行い同期性を担保するのに使用します。

 

ダイアログ作成

ダイアログ作成には2つのものが必要です。必要なウィジットを記したリソーステーブルとウィジットのための初期値を与えられたウィンドウプロシージャです。2つが用意出来たら関数(GUI_CreateDialogBox() または GUI_ExecDialogBox())を呼び出すことでダイアログを作成することができます。

 

リソーステーブル

ダイアログボックスを作るときブロッキングかノンブロッキングで作ります。ダイアログに必要なウィジットをすべて記したリソーステーブルは最初に定義されていなければなりせん。リソーステーブルの例をつぎに示します。この例は手書きで作られましたが、GUIビルダーを用いて作成することも可能です。

static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  { FRAMEWIN_CreateIndirect,   "Dialog",   0,              10, 10, 180, 230, FRAMEWIN_CF_MOVEABLE, 0 },
  { BUTTON_CreateIndirect,     "OK",       GUI_ID_OK,     100, 5, 60, 20 },
  { BUTTON_CreateIndirect,     "Cancel",   GUI_ID_CANCEL, 100, 30, 60, 20 },
  { TEXT_CreateIndirect,       "LText",    0,              10, 55, 48, 15, TEXT_CF_LEFT },
  { TEXT_CreateIndirect,       "RText",    0,              10, 80, 48, 15, TEXT_CF_RIGHT },
  { EDIT_CreateIndirect,        NULL,      GUI_ID_EDIT0,   60, 55, 100, 15, 0, 50 },
  { EDIT_CreateIndirect,        NULL,      GUI_ID_EDIT1,   60, 80, 100, 15, 0, 50 },
  { TEXT_CreateIndirect,       "Hex",      0,              10, 100, 48, 15, TEXT_CF_RIGHT },
  { EDIT_CreateIndirect,        NULL,      GUI_ID_EDIT2,   60, 100, 100, 15, 0, 6 },
  { TEXT_CreateIndirect,       "Bin",      0,              10, 120, 48, 15, TEXT_CF_RIGHT },
  { EDIT_CreateIndirect,        NULL,      GUI_ID_EDIT3,   60, 120, 100, 15 },
  { LISTBOX_CreateIndirect,     NULL,      GUI_ID_LISTBOX0,10, 10, 48, 40 },
  { CHECKBOX_CreateIndirect,    NULL,      GUI_ID_CHECK0,  10, 140, 0, 0 },
  { CHECKBOX_CreateIndirect,    NULL,      GUI_ID_CHECK1,  30, 140, 0, 0 },
  { SLIDER_CreateIndirect,      NULL,      GUI_ID_SLIDER0, 60, 140, 100, 20 },
  { SLIDER_CreateIndirect,      NULL,      GUI_ID_SLIDER1, 10, 170, 150, 30 }
};

 

ダイアログプロシージャサンプルコード
下のダイアログボックスのサンプルは下にある空のダイアログプロシージャから生成されたものです。このコードはダイアログプロシージャを作るときのテンプレートとしてご利用下さい。

/*********************************************************************
*
* Dialog procedure
*/
static void _cbCallback(WM_MESSAGE * pMsg) {
  switch (pMsg->MsgId) {
    default:
      WM_DefaultProc(pMsg);
}
}


この例では、ダイアログポックスは以下のコードで表示します。

GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);


表示されるダイアログボックスの概観です。(実際の概観はお客様の設定などによって変化します。)
EmwinDialogsBlank
ダイアログボックを生成するとすべてのウィジットは表示されますが、上図のようにまだ値は空のままです。これはダイアログプロシージャにまだ初期値を与えていないためです。初期値とウィジット間の連携はダイアログプロシージャで定義されている必要があります。

 

ダイアログの初期化
初期値の設定の仕方。通常はダイアログプロシージャにWM_INIT_DIALOGメッセージを送ることで初期化が行われます。プログラムのコード例は以下のようです。

/*********************************************************************
*
* Dialog procedure
*/
static void _cbCallback(WM_MESSAGE * pMsg) {
  int NCode, Id;
  WM_HWIN hEdit0, hEdit1, hEdit2, hEdit3, hListBox;
  WM_HWIN hWin = pMsg->hWin;
  switch (pMsg->MsgId) {
  case WM_INIT_DIALOG:
    /* Get window handles for all widgets */
    hEdit0 = WM_GetDialogItem(hWin, GUI_ID_EDIT0);
    hEdit1 = WM_GetDialogItem(hWin, GUI_ID_EDIT1);
    hEdit2 = WM_GetDialogItem(hWin, GUI_ID_EDIT2);
    hEdit3 = WM_GetDialogItem(hWin, GUI_ID_EDIT3);
    hListBox = WM_GetDialogItem(hWin, GUI_ID_LISTBOX0);
    /* Initialize all widgets */
    EDIT_SetText(hEdit0, "EDIT widget 0");
    EDIT_SetText(hEdit1, "EDIT widget 1");
    EDIT_SetTextAlign(hEdit1, GUI_TA_LEFT);
    EDIT_SetHexMode(hEdit2, 0x1234, 0, 0xffff);
    EDIT_SetBinMode(hEdit3, 0x1234, 0, 0xffff);
    LISTBOX_SetText(hListBox, _apListBox);
    WM_DisableWindow (WM_GetDialogItem(hWin, GUI_ID_CHECK1));
    CHECKBOX_Check( WM_GetDialogItem(hWin, GUI_ID_CHECK0));
    CHECKBOX_Check( WM_GetDialogItem(hWin, GUI_ID_CHECK1));
    SLIDER_SetWidth( WM_GetDialogItem(hWin, GUI_ID_SLIDER0), 5);
    SLIDER_SetValue( WM_GetDialogItem(hWin, GUI_ID_SLIDER1), 50);
    break;
  default:
    WM_DefaultProc(pMsg);
  )
}


初期化されたダイアログボックスの様子は次のように変化します。
EmwinDialogsAfterInit

 

ダイアログの動作定義
ダイアログを初期化したら、残り必要なのはダイアログボックスが目的の機能を果たすように書くウィジットの動作を定義することです。ダイアログボックスを以下のように書き換えます。

/*********************************************************************
*
* Dialog procedure
*/
static void _cbCallback(WM_MESSAGE * pMsg) {
  int NCode, Id;
  WM_HWIN hEdit0, hEdit1, hEdit2, hEdit3, hListBox;
  WM_HWIN hWin = pMsg->hWin;
  switch (pMsg->MsgId) {
  case WM_INIT_DIALOG:
    /* Get window handles for all widgets */
    hEdit0 = WM_GetDialogItem(hWin, GUI_ID_EDIT0);
    hEdit1 = WM_GetDialogItem(hWin, GUI_ID_EDIT1);
    hEdit2 = WM_GetDialogItem(hWin, GUI_ID_EDIT2);
    hEdit3 = WM_GetDialogItem(hWin, GUI_ID_EDIT3);
    hListBox = WM_GetDialogItem(hWin, GUI_ID_LISTBOX0);
    /* Initialize all widgets */
    EDIT_SetText(hEdit0, "EDIT widget 0");
    EDIT_SetText(hEdit1, "EDIT widget 1");
    EDIT_SetTextAlign(hEdit1, GUI_TA_LEFT);
    EDIT_SetHexMode(hEdit2, 0x1234, 0, 0xffff);
    EDIT_SetBinMode(hEdit3, 0x1234, 0, 0xffff);
    LISTBOX_SetText(hListBox, _apListBox);
    WM_DisableWindow (WM_GetDialogItem(hWin, GUI_ID_CHECK1));
    CHECKBOX_Check( WM_GetDialogItem(hWin, GUI_ID_CHECK0));
    CHECKBOX_Check( WM_GetDialogItem(hWin, GUI_ID_CHECK1));
    SLIDER_SetWidth( WM_GetDialogItem(hWin, GUI_ID_SLIDER0), 5);
    SLIDER_SetValue( WM_GetDialogItem(hWin, GUI_ID_SLIDER1), 50);
    break;
  case WM_KEY:
    switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key) {
    case GUI_ID_ESCAPE:
      GUI_EndDialog(hWin, 1);
      break;
    case GUI_ID_ENTER:
      GUI_EndDialog(hWin, 0);
      break;
    }
    break;
  case WM_NOTIFY_PARENT:
    Id = WM_GetId(pMsg->hWinSrc); /* Id of widget */
    NCode = pMsg->Data.v; /* Notification code */
    switch (NCode) {
    case WM_NOTIFICATION_RELEASED: /* React only if released */
      if (Id == GUI_ID_OK) { /* OK Button */
        GUI_EndDialog(hWin, 0);
      }
      if (Id == GUI_ID_CANCEL) { /* Cancel Button */
        GUI_EndDialog(hWin, 1);
      }
      break;
    case WM_NOTIFICATION_SEL_CHANGED: /* Selection changed */
      FRAMEWIN_SetText(hWin, "Dialog - sel changed");
      break;
    default:
      FRAMEWIN_SetText(hWin, "Dialog - notification received");
    }
    break;
  default:
    WM_DefaultProc(pMsg);
  }
}

 

API索引

下の表はダイアログに関する操作のAPIです。

API説明
ダイアログボックス
GUI_CreateDialogBox ノンブロッキングダイアログ(モードレス)の作成
GUI_ExecCreatedDialog ダイアログの作成実行
GUI_ExecDialogBox ダイアログの実行
GUI_EndDialog ダイアログの終了
メッセージボックス
GUI_MessageBox メッセージボックスの作成実行
MESSAGEBOX_Create メッセージボックスの作成

emWinホームに戻る 


SEGGER
RTOS&Middleware