2016-06-19 14 views
1

私はCでwindow.cを1つ試してみました。ウィンドウ7上でgccでwindow.exeにコンパイルしました。コマンドコンソールでwindow.exeを実行すると、私は同じコンソールで他のコマンドを実行することはできません、なぜですか?コマンドコンソールにputty.exeや他のウィンドウアプリケーションをexe拡張子で試してみると、プログラムが実行されたり読み込まれたりすると、コマンドコンソールが終了します。理由は、main.cがwindow.cに含まれていないかどうかです。そして、他の質問は、window.c内のコードがプログラムにmain()を含めずにself-executedモードで実行できる理由です。 は、それが動作しますが、コマンドコンソールは、私はなぜ、同じコンソール内の他のコマンドを実行することはできませんうちに終了することはできませんウィンドウ7のバックグラウンドでCウィンドウプログラムを実行するには

#include <windows.h> 

const char g_szClassName[] = "myWindowClass"; 

// Step 4: the Window Procedure 
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
switch(msg) 
{ 
    case WM_CLOSE: 
     DestroyWindow(hwnd); 
    break; 
    case WM_DESTROY: 
     PostQuitMessage(0); 
    break; 
    default: 
     return DefWindowProc(hwnd, msg, wParam, lParam); 
} 
return 0; 
} 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
LPSTR lpCmdLine, int nCmdShow) 
{ 
WNDCLASSEX wc; 
HWND hwnd; 
MSG Msg; 

//Step 1: Registering the Window Class 
wc.cbSize  = sizeof(WNDCLASSEX); 
wc.style   = 0; 
wc.lpfnWndProc = WndProc; 
wc.cbClsExtra = 0; 
wc.cbWndExtra = 0; 
wc.hInstance  = hInstance; 
wc.hIcon   = LoadIcon(NULL, IDI_APPLICATION); 
wc.hCursor  = LoadCursor(NULL, IDC_ARROW); 
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
wc.lpszMenuName = NULL; 
wc.lpszClassName = g_szClassName; 
wc.hIconSm  = LoadIcon(NULL, IDI_APPLICATION); 

if(!RegisterClassEx(&wc)) 
{ 
    MessageBox(NULL, "Window Registration Failed!", "Error!", 
     MB_ICONEXCLAMATION | MB_OK); 
    return 0; 
} 

// Step 2: Creating the Window 
hwnd = CreateWindowEx(
    WS_EX_CLIENTEDGE, 
    g_szClassName, 
    "The title of my window", 
    WS_OVERLAPPEDWINDOW, 
    CW_USEDEFAULT, CW_USEDEFAULT, 600, 300, 
    NULL, NULL, hInstance, NULL); 

if(hwnd == NULL) 
{ 
    MessageBox(NULL, "Window Creation Failed!", "Error!", 
     MB_ICONEXCLAMATION | MB_OK); 
    return 0; 
} 

ShowWindow(hwnd, nCmdShow); 
UpdateWindow(hwnd); 

// Step 3: The Message Loop 
while(GetMessage(&Msg, NULL, 0, 0) > 0) 
{ 
    TranslateMessage(&Msg); 
    DispatchMessage(&Msg); 
} 
return Msg.wParam; 
} 
+0

これはWindowsアプリケーションだからです。 ウィンドウを作成するコンソールアプリケーションではありません – beyrem

+0

私たちのために例を挙げてください。 Putty.exeはコンソールアプリケーションです。 – aabb

答えて

1

を教えてください?コマンドコンソールにputty.exeや他のウィンドウアプリケーションをexe拡張子で試してみると、プログラムが実行されたり読み込まれたりすると、コマンドコンソールが終了します。コンソールから起動

A Windowsアプリケーションべきコンソールウィンドウとないブロック、さらに相互作用。私はputty.exeについて何も知らないので、notepad.exeを例に挙げてみましょう。これは標準のWindowsアプリケーションです。コマンドラインから実行すると、メモ帳が新しいウィンドウで起動し、C:プロンプトが表示されます。あなたは正常であると完全に正しいです。

ここに示したように、あなたのコードは正常に動作します。他の何かが間違っています。おそらくあなたのコンパイラやリンカの設定です。私はあなたがコンソールサブシステムをターゲットにしているかもしれないが、リンカーはあなたが間違ったエントリーポイントを持っていると不平を言うべきであると示唆したい。 (少なくともMicrosoftのツールチェーンはGCCについてはあまりよく分かりませんが)それは少なくともチェックするものです。あなたが構築するときにスイッチ-mwindowsを渡していることを確認してください。

なぜmain.cがwindow.cに含まれているかどうか、そして、他の質問は、window.c内のコードがプログラムにmain()を含めずにself-executedモードで実行できる理由です。

いいえ、それは関係ありません。コードにmain()関数が存在しない理由は、WinMain()関数がエントリポイントとして機能しているためです。

技術的には、WinMain()は、というユーザー定義のエントリポイントです。これはthe conventional name and signature for the function in Windows applicationsです。 main()と似ていると考えることができますが、実際には、main()の機能はまだ存在し、ライブラリコードに埋め込まれています。 Windowsアプリケーションを構築するときにリンクするCランタイムライブラリは、実際のエントリポイントを定義します。いくつかの早期初期化タスクを実行してから、ユーザ定義のエントリポイントWinMain()を呼び出します。

アプリケーションをデバッガでシングルステップ実行すると、これが実際に動作しますが、ブレークポイントをWinMain()の先頭に置いた場合は、それを見逃すことになります。これは、コードが最初に実行を開始するところですが、私が説明したように、最初に実行してWinMain()に制御を渡すコードがあります。したがって、EXEの最初の命令を踏み始める必要があります。 Visual Studioでは、F11を押すだけでステップインします。私はどのデバッガを使用しているのか分かりません。そのドキュメントを確認する必要があります。

これはまったく心配する必要はありません。なぜなら、それはあなたが本当に理解する必要がない本質的に秘密であるからです。 WinMain()は、Windowsアプリケーションを作成するときにmain()と同等であると考えてください。

+0

詳細な返信をありがとうございます。アプリケーションを実行し続けるためのwhileループがあります。コンソールが終了できない理由はありますか? (のGetMessage(&メッセージ、NULL、0、0)> 0)。すなわち、標準のWindowsメッセージループである理由であることができない – aabb

+0

号 {(&Msg); TranslateMessage(&Msg); DispatchMessageを}がすべてのWindowsアプリケーションは、同様に有しながらメモ帳。 –

+0

その理由はgccコンパイラの問題に関連しているようです。そのオプションは – aabb

関連する問題