Updating the Screen

LastUpdate: 05-Feb-2002
Created: 05-Jun-2000
(c) Copyright 1997-2002 by H.Fujii

[前へ][次へ]

Dialog 中の文字列を取得することができるようになりましたが、この ままでは正しく読み込まれたかどうか確認できません。そこで、Dialog から 読み込んだ文字列をスクリーンへ表示してみることにします。今、 変数 mycmndstrmycmndlen に値が設定されていますから、 以前にやった OnPaint() を書き換えるのが簡単です。

/* paint.c */

#define STRICT
#include 
#include "myvariab.h"

void OnPaint( HDC hdc )
{
  if( mycmndlen > 0 )
    TextOut( hdc, 0, 0, mycmndstr, mycmndlen );
}

しかし、これだけでは足りません。Window を書き換える必要があることを システムに知らせなければなりません。これを行うのに、ここでは Window 画面 に変更された領域があるという通知を行う InvalidateRect() 関数を 使います。この関数は、単に変更領域があることをシステムに通知する だけで、これにより Windows メッセージがすぐに発生するわけではありません。 システムは適当な頃合を見計らって、WM_PAINT メッセージを発生し ますが、それまで変更領域を溜め込みます。ただし、領域全体に変更が加えられた 場合は、WM_PAINT メッセージが発生します。そこで、ここでは全領域 に変更可能性ありとして、InvalidateRect() の第2引数を NULL にして呼び出します。これにより WM_PAINT メッセージが発生し、 文字列が表示されるようになります。具体的には、WndProc() で、
  case WM_COMMAND:
    wNotifyCode = HIWORD( wParam );
    wID = LOWORD( wParam );
    switch( wID )
    {
         :
    case ID_FILE_CMND:
      hInst = (HINSTANCE)GetWindowLong( hwnd, GWL_HINSTANCE );
      if( DialogBox( hInst, "MyCmndDlg", hwnd, (DLGPROC)MyCmndProc ) == IDOK )
        InvalidateRect( hwnd, NULL, TRUE );
      break;
         :
とします。

なお、強制的に当該 Window に WM_PAINT メッセージを送りたい場合は、 UpdateWindow()関数を呼び出します。ただし、この場合も変更領域が 存在しないと、メッセージは送られませんので、その前に InvalidateRect() 関数を呼び出して変更領域があることをシステムに知らせておく必要があります。


さて、これで一応動くことは動くのですが、mycmndlenmycmndstr の初期化が行われていません。また、Dialog の文字入力窓の初期化も行われて ません。これは大変危険なので、初期化操作を入れます。mycmndlenmycmndstr については、WinMain() の中で、Window を Create する 前に行うものとして、別関数 initapp() を用意することにします。

/* initapp.c */
#define STRICT
#include <windows.h>
#include "myvariab.h"

BOOL
initapp( void )
{
  /* Initialize variables */
  mycmndlen = 0;
  mycmndstr[0] = (TCHAR)0;
  return TRUE;
}
これに対応して、WinMain() では、CreateWindow() の前に initapp() の呼び出しを行うことにして、
       :
BOOL initapp( void );
       :
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  LPSTR lpCmdLine, int nCmdShow )
{
       :

  /* Initialize variables etc. */
  if( !initapp() )
    return 0;

  /* Create our window. */
  hwnd = CreateWindow( MY_CLASS_NAME, MY_WINDOW_TITLE, WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
    (HWND)NULL, (HMENU)NULL, hInstance, (LPVOID)NULL );
       :
とします。

一方、Dialog の方の初期化は、WM_INITDIALOG メッセージに対する 応答で行います。

BOOL CALLBACK MyCmndProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
  WORD wNotifyCode;
  WORD wID;

  switch( uMsg )
  {
  case WM_INITDIALOG:
    SetDlgItemText( hDlg, IDC_EDIT_MYCMND, mycmndstr );
    return TRUE;
  case WM_COMMAND:
        :
リソースファイルの MyCmndDlg の最初の item が、この EDITTEXT に なっているので、初期化が正しく行われることにより、Dialog が開いた時に、 ここにフォーカスが設定されます。また、TAB によるフォーカスの 移動を行うために、リソースファイルの、この Dialog の各 item に WS_TABSTOP をつけておきましょう。具体的には
MyCmndDlg DIALOG DISCARDABLE 0, 0, 128, 64
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "My Command Dialog"
BEGIN
  EDITTEXT IDC_EDIT_MYCMND, 24, 10, 96, 12, ES_AUTOHSCROLL | WS_TABSTOP
  DEFPUSHBUTTON "Ok", IDOK, 24, 24, 48, 12, WS_TABSTOP
  PUSHBUTTON "Cancel", IDCANCEL, 72, 24, 48, 12, WS_TABSTOP
END
のようにします。


[前へ][次へ]