ファイルを読むと、私はジョニーですォォォォォォォォ・・

解決


りんご  2005-12-24 20:30:34  No: 60038

EDITにファイルの中身を読み込むプログラムを作りたくて、

//--------------------------------------------------------------------------------------
//  ■ファイルをEDITに読込■ Sample NO.56
//
//                                          「Programming Library」
//                                           http://madia.world.coocan.jp/ 
//                                           papy@hamal.freemail.ne.jp
//                                           Copyright(C)2001/6/18 Takeshi Okamoto(PAPY)
//--------------------------------------------------------------------------------------

#include <windows.h>

#define ID_EDIT              100
HWND hEdit;

//コールバックプロシージャ&メッセージハンドラ
LRESULT CALLBACK  WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);

//------------------------------------------------------
//■関数 ScreenCenterX(ローカル)
//■用途 ウインドウを中央にする為にX座標(LEFT)を算出する
//■引数
//  Width ...ウインドウの横幅
//------------------------------------------------------
int ScreenCenterX(int Width)

   int X;
   X = (GetSystemMetrics(SM_CXSCREEN)- Width) / 2;
   if (X<0) X=0;
   return(X);
}

//------------------------------------------------------
//■関数 ScreenCenterY(ローカル)
//■用途 ウインドウを中央にする為にY座標(TOP)を算出する
//■引数
//  Height ...ウインドウの縦幅
//------------------------------------------------------
int ScreenCenterY(int Height)

   int Y;
   Y= (GetSystemMetrics(SM_CYSCREEN)- Height) / 2;
   if (Y<0) Y=0;
   return(Y);
}

//------------------------------------------------------
//■関数 CreateMainWindow(ローカル)
//■用途 メインウインドウを作成する
//■引数
//  Width       ...ウインドウの横幅
//  Height      ...ウインドウの縦幅
//  Caption     ...タイトル名
//  hInstance   ...インスタンスハンドル
//  nCmdShow    ...ウインドウの表示形態
//  lpfnWndProc ...コールバックプロシージャ
//  dwstyle     ...ウインドウスタイル
//  dwExstyle   ...拡張ウインドウスタイル
//  MenuID      ...メニューのID
//  hIcon       ...アイコン
//■戻り値
//  ウインドウのハンドル
//------------------------------------------------------
HWND CreateMainWindow(int Width,int Height,LPCTSTR Caption,HINSTANCE hInstance,int nCmdShow,WNDPROC lpfnWndProc, DWORD dwstyle,DWORD dwExstyle,LPCTSTR MenuID,HICON hIcon)
{
    HWND hWnd;         //メインウインドウのハンドル
    WNDCLASS myClass;  //WNDCLASS構造体
    
    //WNDCLASS構造体を0で初期化
    ZeroMemory(&myClass,sizeof(WNDCLASS));
 
//--->WNDCLASS構造体の設定&ウインドウクラスの登録

    myClass.style =CS_HREDRAW | CS_VREDRAW;       //ウインドウスタイルを設定 
    myClass.lpfnWndProc   = lpfnWndProc;          //コールバックプロシージャへのポインタ
    myClass.hInstance=hInstance;                  //インスタンスハンドルを設定
    myClass.hCursor=LoadCursor(NULL, IDC_ARROW);  //カーソルの設定(Windows標準リソースを使用)  
    myClass.hbrBackground=(HBRUSH)COLOR_WINDOW;   //ウインドウの背景を設定(デフォルトカラー)
    myClass.lpszClassName="TForm";                //クラス名の設定(Borland Delphi風)  
    myClass.hIcon =hIcon;                         //アイコンの指定
    myClass.lpszMenuName=NULL;                  //メニューの設定

    //ウィンドウ クラスdを登録
    RegisterClass(&myClass); 
    
//--->ウインドウの作成&表示
   
  //メインウインドウの生成
  hWnd = CreateWindowEx(
           dwExstyle,            //拡張ウインドウスタイル
           "TForm",              //登録されたクラス名のアドレス 
           Caption,              //ウインドウ名
           dwstyle,              //ウインドウスタイルを設定
           ScreenCenterX(Width), //X座標の位置設定
           ScreenCenterY(Height),//Y座標の位置設定
           Width,                //横幅を設定
           Height,               //縦幅を設定
           NULL,                 //親ウインドウを設定
           NULL,                 //メニューを設定
           hInstance,            //インスタンスを識別
           NULL);                //作成したウインドウに渡すデータへのポインタ
 
  //ウインドウの表示(表示方法はnCmdShowに従う)
  ShowWindow(hWnd, nCmdShow);
  return(hWnd);
}

//------------------------------------------------------
//■関数名  ControlCreate
//■用途    ウインドウ(コントロール)を作成
//■引数
//       hwndParent ...親ウインドウのハンドル
//       Left       ...作成するウインドウの左隅のX座標
//       Top        ...作成するウインドウの左隅のY座標
//       Width      ...作成するウインドウの横幅
//       Height     ...作成するウインドウの縦幅
//       dwExStyle  ...ウインドウの拡張フラグ
//       dwFlag     ...ウインドウの作成フラグ
//       Caption    ...作成するウインドウのキャプション
//       ClassName  ...作成するウインドウクラス名
//       ChildID    ...子ウインドウの識別子
//       hInstance  ...インスタンスハンドル 
//■戻り値
//子ウインドウのハンドル
//------------------------------------------------------
 HWND CreateControlWindow(HWND hwndParent, int Left, int Top,int Width, int Height,int dwExStyle ,int dwFlag ,LPCTSTR Caption, LPCTSTR ClassName,HMENU ChildID,HINSTANCE hInstance)
 { 
 return CreateWindowEx(dwExStyle,ClassName,Caption,WS_CHILD | WS_VISIBLE | dwFlag    ,
                         Left, Top, Width, Height, hwndParent, ChildID, hInstance, NULL);
 }

//--------------------------------------------------------
//■関数 WinMain
//■用途 メインの関数 
//■引数
// hInstance    ...現在のインスタンスのハンドル
// hPrevInstance...以前のインスタンスのハンドル
// pszCmdLine   ...コマンド ラインのアドレス
// nCmdShow     ...ウィンドウの表示状態
//--------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
   MSG msg;

  //メインウインドウを作成
  CreateMainWindow(400,400,"ファイルをEDITに読込む",hInstance,nCmdShow,(WNDPROC)WindowProc,
       WS_OVERLAPPEDWINDOW,WS_EX_CONTROLPARENT | WS_EX_WINDOWEDGE,NULL,LoadIcon(NULL,MAKEINTRESOURCE(IDI_APPLICATION)));

  //送られてくるメッセージを翻訳してプロシージャに渡す  
  while (GetMessage(&msg, NULL, 0, 0)) 
  {
    TranslateMessage(&msg); 
    DispatchMessage(&msg);   
  } 
 return (msg.wParam);
}
//------------------------------------------------------
// ■関数 WindowProc
// ■用途 メインウインドウに送られるメッセージを処理
// ■引数
//   hwnd    ...ウインドウのハンドル
//   uMsg    ...メッセージID
//   wParam  ...第1メッセージ パラメータ    
//   lParam  ...第2メッセージ パラメータ
//------------------------------------------------------
LRESULT CALLBACK  WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{  
  switch (uMsg)
    {
  case WM_CREATE:
        { 
      char szFile[MAX_PATH]="test.txt";
      char *buffer;
      HANDLE hFile;
      DWORD _FileSize,Dummy;
                        
      //コントロール作成 
      hEdit=  CreateControlWindow(hwnd,10,10,370,355,WS_EX_CLIENTEDGE,
                                                ES_AUTOVSCROLL |ES_WANTRETURN |ES_MULTILINE|ES_AUTOHSCROLL |WS_VSCROLL|WS_HSCROLL ,"","EDIT",(HMENU)ID_EDIT,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE));    

      //EDitの内容をクリアする
      SetWindowText(hEdit, "");

      // [main.cpp]ファイルを開く
      if ((hFile = CreateFile((LPCTSTR)szFile,
               GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,(HANDLE)NULL)) != (HANDLE)-1)
      {
           // ファイルサイズ取得
           _FileSize = GetFileSize(hFile, NULL);
           if (_FileSize != 0)
           {                
             //最大で60kまで読込む(EDITは約60kまでしか読込めない)<---これ以上のファイルを読込んだらシステムがハングアップします(^^;
             if (_FileSize>60000) _FileSize=60000;
             // メモリブロックの割り当て
             buffer = (char *)GlobalAlloc(GMEM_FIXED, _FileSize );
             if (buffer != NULL)
             {
              //バッファの内容を読込む
              ReadFile(hFile,(LPVOID)buffer, _FileSize, &Dummy, NULL);
              //EDitに内容を送る
              SetWindowText(hEdit, buffer);
              // ファイルを閉じる
              CloseHandle(hFile);
              GlobalFree(buffer);
             }
           }
      }
      break;
            }
   case WM_SIZE:
             MoveWindow(hEdit,0,0,LOWORD(lParam),HIWORD(lParam),true);
             break;
   case WM_DESTROY:
             PostQuitMessage(0);
             break;
   default:return(DefWindowProc(hwnd, uMsg, wParam, lParam)); 
    }
  return (0);
}

このコードをコンパイルして実行すると
test.txtの中身は、

こんにちわ
私はジョニーです

なのに


こんにちわ
私はジョニーですォォォォォォォォ・・

と表示されます
なぜでしょうか?


Blue  2005-12-24 20:40:26  No: 60039

終端文字を含んで文字列となります。
ファイルサイズはバイナリでの値になりますので、
終端文字を含んでいません。

> SetWindowText(hEdit, buffer);
はbufferを'\0'まで表示するものです。

ということは、解決策はわかりますよね?


りんご  2005-12-24 22:43:02  No: 60040

buffer[Dummy] = "\0";
としたらできました
ありがとうございました


επιστημη  2005-12-24 22:54:04  No: 60041

それにしても引用長すぎ。
"現象を再現/説明するに十分なだけの短いコード"でお願いします。
そこまで原因を絞り込む作業/努力を怠っていてはスキルの向上は見込めません。


Blue  2005-12-24 22:58:21  No: 60042

> buffer[Dummy] = "\0";
だけ変更したら不味いでしょう。
GlobalAllocで確保した領域外にアクセスしています。


Blue  2005-12-25 02:57:45  No: 60043

って良く見たら、
> buffer[Dummy] = "\0";
型がちゃうのうでは?

_FileSize++; /* '\0' 分領域を追加 */
> if (_FileSize>60000) _FileSize=60000;
> // メモリブロックの割り当て
> buffer = (char *)GlobalAlloc(GMEM_FIXED, _FileSize );
> if (buffer != NULL)
> {
>     //バッファの内容を読込む
      ReadFile(hFile,(LPVOID)buffer, _FileSize - 1, &Dummy, NULL);
      // '\0'の付加
      buffer[ Dummy ] = '\0';
>     //EDitに内容を送る
>     SetWindowText(hEdit, buffer);

に変更すべきです。

ちなみに、
> // ファイルを閉じる
> CloseHandle(hFile);
のタイミングは間違っています。正常の時だけしか上手く動作しません。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加