今、コンソールを持つ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;
}
詳しく調べてないけど、
コンソールアプリでは行われる初期化が WINDOW ベースでは行われないから、
でしょう。
例えばコンソールアプリでしか行われていないであろう初期化の中には
stdin/stdout のオープン(Windows ハンドルとの結合) とか
stdout と cout との結合とかがありそうです。
必要な初期化を行わないと動かないと思います。