MFCアプリケーションにアロケートされた、コンソールについての質問

[戻る]
f_take2000 2003/12/10(水) 10:46:06
今、コンソールを持つMFCアプリケーションを作っています。
(Win32 システムサービス プログラミングのコンソールの章の、例”MFCプログラム内に
コンソールをアロケートする”)
このプログラムは、ボタンが押されると、アロケートされた、コンソールに、"hello 
world"を出力するのですが、
WriteFile: システムコールでは、うまく出力されますが、
cout: standard io library は、出力されません。

WriteFileには、GetStdHandle(STD_OUTPUT_HANDLE)で取得した、ファイルハンドルを渡し
ています。

何が、問題なのでしょうか?

環境:windows2000 VC++6.0


以下は、コード全文です。
コンパイルは、コマンドプロンプトから以下のようにしてできます。

prompt>cl button.cpp -MD -D_AFXDLL /GX  /c
prompt>link button.obj /SUBSYSTEM:WINDOWS


#include <afxwin.h>
#include <iostream>

#define IDB_BUTTON 100

HANDLE consoleStdout,consoleStdin;

class CButtonApp : public CWinApp
{
  public:
    virtual BOOL InitInstance();
};

CButtonApp ButtonApp;

class CButtonWindow : public CFrameWnd
{
  CButton *button;
public: 
  CButtonWindow();
  ~CButtonWindow();
  afx_msg void HandleButton();

  DECLARE_MESSAGE_MAP()
};

void CButtonWindow::HandleButton()
{
  DWORD n;
  Beep(700,100);

  WriteFile(consoleStdout,"hello\n",6,&n,0);
  std::cout<<"hello world\n"<<std::endl;
  std::cout.flush();
}

BEGIN_MESSAGE_MAP(CButtonWindow,CFrameWnd)
  ON_COMMAND(IDB_BUTTON,HandleButton)
END_MESSAGE_MAP()

BOOL CButtonApp::InitInstance()
{

  BOOL success;
  FreeConsole();
  success = AllocConsole();
  if(!success)
  {
    return FALSE;
  }

  consoleStdin = GetStdHandle(STD_INPUT_HANDLE);
  consoleStdout = GetStdHandle(STD_OUTPUT_HANDLE);


  if(consoleStdin == consoleStdout || consoleStdin == INVALID_HANDLE_VALUE || 
consoleStdout == INVALID_HANDLE_VALUE)
    return FALSE;
  m_pMainWnd = new CButtonWindow;
  m_pMainWnd->ShowWindow(m_nCmdShow);
  m_pMainWnd->UpdateWindow();

  return TRUE;
}

CButtonWindow::CButtonWindow()
{
  CRect r;

  Create(NULL,"CButton Tests",
    WS_OVERLAPPEDWINDOW,
    CRect(0,0,200,200));
  GetClientRect(&r);

  r.InflateRect(-20,-20);

  button = new CButton();
  button->Create("Push me",
    WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
    r,
    this,
    IDB_BUTTON);
}
CButtonWindow::~CButtonWindow()
{
  delete button;
}

tetrapod 2003/12/10(水) 16:39:24
詳しく調べてないけど、
コンソールアプリでは行われる初期化が WINDOW ベースでは行われないから、
でしょう。
例えばコンソールアプリでしか行われていないであろう初期化の中には
stdin/stdout のオープン(Windows ハンドルとの結合) とか
stdout と cout との結合とかがありそうです。
必要な初期化を行わないと動かないと思います。

古いスレッドには追加発言できません。