运行C ++应用程序时摆脱黑色控制台窗口

时间:2012-01-08 02:18:25

标签: c++ winapi netbeans

我正在使用Netbeans 7.1来玩我发现的here的AI教程。

编辑:我正在使用GCC编译器。

我已经完成了所有工作,但我似乎无法让应用程序编译并运行Windows子系统...应用程序似乎是为Windows API正确编写的,以及源代码附带的可执行文件该网站的文件启动时不会生成我自己的可执行文件创建的黑色控制台窗口。

我尝试添加-mwindows作为链接器的选项,我尝试了-Wl,-subsystem,windows。这些都不适合我。我在下面提供了main.cpp。

#define WIN32_LEAN_AND_MEAN

#include <windows.h> 

#include <stdlib.h>
#include <time.h>


#include "utils.h"
#include "CController.h"
#include "CTimer.h"
#include "resource.h"
#include "CParams.h"


// edited this out, still not working

// #pragma comment(链接器,“/ SUBSYSTEM:windows / ENTRY:mainCRTStartup”)

///////////////////////GLOBALS ////////////////////////////////////

char*           szApplicationName = "Smart Sweepers v1.0";
char*           szWindowClassName = "sweeper";


//The controller class for this simulation
CController*    g_pController    = NULL; 

//create an instance of the parameter class.
CParams   g_Params;

//---------------------------- Cleanup ----------------------------------
//
//  simply cleans up any memory issues when the application exits
//-----------------------------------------------------------------------
void Cleanup()
{
    if (g_pController) 

        delete g_pController;
}
//-----------------------------------WinProc-----------------------------
//
//-----------------------------------------------------------------------
LRESULT CALLBACK WindowProc(HWND hwnd, 
                                        UINT msg, 
                            WPARAM wparam, 
                            LPARAM lparam)
{
    //these hold the dimensions of the client window area
    static int cxClient, cyClient;

    //used to create the back buffer
    static HDC        hdcBackBuffer;
    static HBITMAP  hBitmap;
    static HBITMAP  hOldBitmap; 


    switch(msg)
    {   
        case WM_CREATE: 
        {
            //seed the random number generator
            srand((unsigned) time(NULL));

            //get the size of the client window
            RECT rect;
            GetClientRect(hwnd, &rect);

            cxClient = rect.right;
            cyClient = rect.bottom;

            //setup the controller
            g_pController = new CController(hwnd);

                //create a surface for us to render to(backbuffer)
            hdcBackBuffer = CreateCompatibleDC(NULL);

            HDC hdc = GetDC(hwnd);

            hBitmap = CreateCompatibleBitmap(hdc,
                                                            cxClient,
                                                            cyClient);
            ReleaseDC(hwnd, hdc);

            hOldBitmap = (HBITMAP)SelectObject(hdcBackBuffer, hBitmap); 
        } 

        break;

        //check key press messages
        case WM_KEYUP:
        {
            switch(wparam)
            {

                case VK_ESCAPE:
                {
                    PostQuitMessage(0);
                }

                break;

                case 'F':
                    {
                        g_pController->FastRenderToggle();
                    }

                    break;

        //reset the demo
        case 'R':
          {
             if (g_pController)
             {
               delete g_pController;
             }

             //setup the new controller
                   g_pController = new CController(hwnd);
          }

          break;

            }//end WM_KEYUP switch
        }

        break;

        //has the user resized the client area?
        case WM_SIZE:
        {
            cxClient = LOWORD(lparam);
            cyClient = HIWORD(lparam);

            //resize the backbuffer accordingly
            SelectObject(hdcBackBuffer, hOldBitmap);

            HDC hdc = GetDC(hwnd);

            hBitmap = CreateCompatibleBitmap(hdc,
                                                             cxClient,
                                                             cyClient);
            ReleaseDC(hwnd, hdc);

            hOldBitmap = (HBITMAP)SelectObject(hdcBackBuffer, hBitmap); 
        } 

        break;

        case WM_PAINT: 
        {
      PAINTSTRUCT ps;

          BeginPaint(hwnd, &ps);

            //fill our backbuffer with white
            BitBlt(hdcBackBuffer,
             0,
             0,
             cxClient,
             cyClient,
             NULL,
             NULL,
             NULL,
             WHITENESS);

            //render the mines and sweepers
            g_pController->Render(hdcBackBuffer);

            //now blit backbuffer to front
            BitBlt(ps.hdc, 0, 0, cxClient, cyClient, hdcBackBuffer, 0, 0, SRCCOPY); 

            EndPaint(hwnd, &ps);
        } 

        break;

        case WM_DESTROY: 
        {
            SelectObject(hdcBackBuffer, hOldBitmap);

            //clean up our backbuffer objects
            DeleteDC(hdcBackBuffer);
            DeleteObject(hBitmap); 

      // kill the application, this sends a WM_QUIT message 
            PostQuitMessage(0);
        } 

        break;

        default:break;

    }//end switch

    // default msg handler 
    return (DefWindowProc(hwnd, msg, wparam, lparam));

}//end WinProc


//-----------------------------------WinMain-----------------------------------------
//  Entry point for our windows application
//-----------------------------------------------------------------------------------
int WINAPI WinMain( HINSTANCE hinstance,
                              HINSTANCE hprevinstance,
                              LPSTR lpcmdline,
                              int ncmdshow)
{

    WNDCLASSEX winclass; 
    HWND       hwnd;     
    MSG        msg;      

    // first fill in the window class stucture
    winclass.cbSize       = sizeof(WNDCLASSEX);
    winclass.style            = CS_HREDRAW | CS_VREDRAW;
    winclass.lpfnWndProc    = WindowProc;
    winclass.cbClsExtra     = 0;
    winclass.cbWndExtra     = 0;
    winclass.hInstance      = hinstance;
    winclass.hIcon            = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_ICON1));
    winclass.hCursor          = LoadCursor(NULL, IDC_ARROW); 
    winclass.hbrBackground= NULL; 
    winclass.lpszMenuName   = NULL;
    winclass.lpszClassName= szWindowClassName;
    winclass.hIconSm      = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_ICON1));


    // register the window class
    if (!RegisterClassEx(&winclass))
    {
        MessageBox(NULL, "Error Registering Class!", "Error", 0);
    return 0;
    }

    // create the window (one that cannot be resized)
    if (!(hwnd = CreateWindowEx(NULL,                                   
                                              szWindowClassName,                        
                                              szApplicationName,                        
                                              WS_OVERLAPPED | WS_VISIBLE | WS_CAPTION | WS_SYSMENU,
                              GetSystemMetrics(SM_CXSCREEN)/2 - CParams::WindowWidth/2,
                              GetSystemMetrics(SM_CYSCREEN)/2 - CParams::WindowHeight/2,                                    
                                              CParams::WindowWidth,
                              CParams::WindowHeight,                
                                              NULL,                                 
                                              NULL,                             
                                              hinstance,                                
                                              NULL)))   
    {
    MessageBox(NULL, "Error Creating Window!", "Error", 0);
        return 0;
    }

    //Show the window
    ShowWindow(hwnd, SW_SHOWDEFAULT );
    UpdateWindow(hwnd);

    //create a timer
    CTimer timer(CParams::iFramesPerSecond);

    //start the timer
    timer.Start();

    // Enter the message loop
    bool bDone = FALSE;

    while(!bDone)
    {

        while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) 
        {
            if( msg.message == WM_QUIT ) 
            {
                //Stop loop if it's a quit message
                bDone = TRUE;
            } 

            else 
            {
                TranslateMessage( &msg );
                DispatchMessage( &msg );
            }
        }

        if (timer.ReadyForNextFrame() || g_pController->FastRender())
        {   
          if(!g_pController->Update())
            {
                //we have a problem, end app
                bDone = TRUE;
            }

            //this will call WM_PAINT which will render our scene
            InvalidateRect(hwnd, NULL, TRUE);
            UpdateWindow(hwnd);
    }                   

    }//end while


    // Clean up everything and exit the app
    Cleanup();
    UnregisterClass( szWindowClassName, winclass.hInstance );

    return 0;

} // end WinMain

1 个答案:

答案 0 :(得分:0)

这看起来有点奇怪,但Windows子系统应用程序使用WinMainCRTStartup作为入口点。因此以下行看起来不一致:

#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")

可能应为"/SUBSYSTEM:windows /ENTRY:WinMainCRTStartup""/SUBSYSTEM:console /ENTRY:mainCRTStartup"

另一方面,我从未尝试用gcc制作Windows应用程序。它可能完全忽略了这个#pragma ......无论如何,试着将它评论出去,看看会发生什么。通常,编译器应该能够在没有编译时参数的情况下选择正确的入口点。